// ProcessingFile to FileProcessed // 1 async and 1 sync state
package main import ( amhelp am ) var ss = states.States func main() { := context.Background() // init the state machine := am.New(nil, states.Schema, nil) .BindHandlers(&Handlers{ Filename: "README.md", Mach: , }) // change the state .Add1(ss.ProcessingFile, nil) // wait for completed := amhelp.WaitForErrAll(, 5*time.Second, , .When1(ss.FileProcessed, nil)) if .Err() != nil { return // expired } else if != nil { println("err: ", ) } else { println("done") } } type Handlers struct { Mach *am.Machine Filename string } // negotiation handler func ( *Handlers) ( *am.Event) bool { // read-only ops // decide if moving fwd is ok // no blocking // lock-free critical section return true } // final handler func ( *Handlers) ( *am.Event) { // read & write ops // no blocking // lock-free critical section := .Mach // clock-based expiration context := .NewStateCtx(ss.ProcessingFile) // unblock .Fork(, , func() { // blocking call := processFile(, .Filename) // re-check the state ctx after a blocking call if .Err() != nil { return // expired } if != nil { .AddErr(, nil) return } // move to the next state in the flow .Add1(ss.FileProcessed, nil) }) } func processFile( context.Context, string) error { time.Sleep(2 * time.Second) return nil }