add flow execution

This commit is contained in:
Michele Balistreri 2021-10-15 10:35:01 +03:00
parent 38d48b590f
commit ffd7ca5f6c
No known key found for this signature in database
GPG Key ID: E9567DA33A4F791A
3 changed files with 112 additions and 24 deletions

94
flow.go
View File

@ -1,6 +1,10 @@
package main
import "errors"
import (
"errors"
"github.com/status-im/status-keycard-go/signal"
)
func NewFlow(storageDir string) (*keycardFlow, error) {
flow := &keycardFlow{
@ -12,20 +16,20 @@ func NewFlow(storageDir string) (*keycardFlow, error) {
}
func (f *keycardFlow) Start(flowType FlowType, params map[string]string) error {
if f.state != IDLE {
if f.state != Idle {
return errors.New("already running")
}
f.flowType = flowType
f.params = params
f.state = RUNNING
f.state = Running
go f.runFlow()
return nil
}
func (f *keycardFlow) Resume(params map[string]string) error {
if f.state != PAUSED {
if f.state != Paused {
return errors.New("only paused flows can be resumed")
}
@ -33,7 +37,7 @@ func (f *keycardFlow) Resume(params map[string]string) error {
f.params[k] = v
}
f.state = RESUMING
f.state = Resuming
f.wakeUp <- struct{}{}
return nil
@ -42,12 +46,12 @@ func (f *keycardFlow) Resume(params map[string]string) error {
func (f *keycardFlow) Cancel() error {
prevState := f.state
if prevState != IDLE {
if prevState != Idle {
return errors.New("cannot cancel idle flow")
}
f.state = CANCELLING
if prevState == PAUSED {
f.state = Cancelling
if prevState == Paused {
f.wakeUp <- struct{}{}
}
@ -55,5 +59,79 @@ func (f *keycardFlow) Cancel() error {
}
func (f *keycardFlow) runFlow() {
repeat := true
var result map[string]string
for repeat {
switch f.flowType {
case GetStatus:
repeat, result = f.switchFlow()
}
}
if f.state != Cancelling {
signal.SendEvent(FlowResult, result)
}
f.state = Idle
}
func (f *keycardFlow) switchFlow() (bool, map[string]string) {
kc := f.connect()
defer f.closeKeycard(kc)
if kc == nil {
return false, map[string]string{"Error": "Couldn't connect to the card"}
}
switch f.flowType {
case GetStatus:
return f.getStatusFlow(kc)
default:
return false, map[string]string{"Error": "Unknown flow"}
}
}
func (f *keycardFlow) pause(action string, status map[string]string) {
signal.SendEvent(action, status)
f.state = Paused
}
func (f *keycardFlow) pauseAndWait(action string, status map[string]string) {
f.pause(action, status)
<-f.wakeUp
}
func (f *keycardFlow) closeKeycard(kc *keycardContext) {
if kc != nil {
kc.stop()
}
}
func (f *keycardFlow) connect() *keycardContext {
kc, err := startKeycardContext()
if err != nil {
return nil
}
f.pause(InsertCard, map[string]string{})
select {
case <-f.wakeUp:
if f.state != Cancelling {
panic("Resuming is not expected during connection")
}
return nil
case <-kc.connected:
if kc.runErr != nil {
return nil
}
return kc
}
}
func (f *keycardFlow) getStatusFlow(kc *keycardContext) (bool, map[string]string) {
return false, nil
}

View File

@ -1,31 +1,37 @@
package main
type FlowType int
type RunState int
type runState int
const (
GET_STATUS FlowType = iota
RECOVER_ACCOUNT
LOAD_ACCOUNT
LOGIN
SIGN
CHANGE_CREDENTIALS
UNPAIR
UNPAIR_OTHERS
DELETE_ACCOUNT_AND_UNPAIR
GetStatus FlowType = iota
RecoverAccount
LoadAccount
Login
Sign
ChangeCredentials
UnpairThis
UnpairOthers
DeleteAccountAndUnpair
)
const (
IDLE RunState = iota
RUNNING
PAUSED
RESUMING
CANCELLING
Idle runState = iota
Running
Paused
Resuming
Cancelling
)
const (
FlowResult = "keycard.flow-result"
InsertCard = "keycard.action.insert-card"
CardInserted = "keycard.action.card-inserted"
)
type keycardFlow struct {
flowType FlowType
state RunState
state runState
wakeUp chan (struct{})
storage string
params map[string]string

View File

@ -7,3 +7,7 @@ const (
func SendKeycardConnected(event interface{}) {
send(EventKeycardConnected, event)
}
func SendEvent(typ string, event interface{}) {
send(typ, event)
}