Skip to content

Instantly share code, notes, and snippets.

@dyrkin
Last active June 28, 2021 13:37
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dyrkin/9af6934ee881744dbae7beaa9cbf3c00 to your computer and use it in GitHub Desktop.
Save dyrkin/9af6934ee881744dbae7beaa9cbf3c00 to your computer and use it in GitHub Desktop.
Decomposed WireTransfer FSM definition
func whenInitial(wt *fsm.FSM) fsm.StateFunction {
return func(event *fsm.Event) *fsm.NextState {
transfer, transferOk := event.Message.(*Transfer)
if transferOk && event.Data == nil {
transfer.source <- transfer.amount
return wt.Goto(AwaitFromState).With(
&WireTransferData{transfer.source, transfer.target, transfer.amount, wt},
)
}
return wt.DefaultHandler()(event)
}
}
func whenAwaitFrom(wt *fsm.FSM) fsm.StateFunction {
return func(event *fsm.Event) *fsm.NextState {
data, dataOk := event.Data.(*WireTransferData)
if dataOk {
switch event.Message {
case Done:
data.target <- data.amount
return wt.Goto(AwaitToState)
case Failed:
go data.client.Send(Failed)
return wt.Stay()
}
}
return wt.DefaultHandler()(event)
}
}
func whenAwaitTo(wt *fsm.FSM, transferred chan bool) fsm.StateFunction {
return func(event *fsm.Event) *fsm.NextState {
data, dataOk := event.Data.(*WireTransferData)
if dataOk {
switch event.Message {
case Done:
transferred <- true
return wt.Stay()
case Failed:
go data.client.Stay()
}
}
return wt.DefaultHandler()(event)
}
}
func newWireTransfer(transferred chan bool) *fsm.FSM {
wt := fsm.NewFSM()
wt.StartWith(InitialState, nil)
wt.When(InitialState)(whenInitial(wt))
wt.When(AwaitFromState)(whenAwaitFrom(wt))
wt.When(AwaitToState)(whenAwaitTo(wt, transferred))
return wt
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment