// Package main is an educational example of a state machine operating on string-based states. // See /examples/basic for a modern example with typed states and schema.
package main import ( amhelp am ) func init() { // load .env _ = godotenv.Load() // am-dbg is required for debugging, go run it // go run github.com/pancsta/asyncmachine-go/tools/cmd/am-dbg@latest // amhelp.EnableDebugging(false) // amhelp.SetEnvLogLevel(am.LogOps) } func main() { // init the state machine := am.New(nil, am.Schema{ "ProcessingFile": { // async Remove: am.S{"FileProcessed"}, }, "FileProcessed": { // async Remove: am.S{"ProcessingFile"}, }, "InProgress": { // sync Auto: true, Require: am.S{"ProcessingFile"}, }, }, &am.Opts{LogLevel: am.LogOps, Id: "raw-strings"}) amhelp.MachDebugEnv() .BindHandlers(&Handlers{ Filename: "README.md", }) // change the state .Add1("ProcessingFile", nil) // wait for completed select { case <-time.After(5 * time.Second): println("timeout") case <-.WhenErr(nil): println("err:", .Err()) case <-.When1("FileProcessed", nil): println("done") } } type Handlers struct { 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 := .Machine() // tick-based context := .NewStateCtx("ProcessingFile") go func() { // block in the background, locks needed if .Err() != nil { return // expired } // blocking call := processFile(.Filename, ) if != nil { .AddErr(, nil) return } // re-check the tick ctx after a blocking call if .Err() != nil { return // expired } // move to the next state in the flow .Add1("FileProcessed", am.A{"beaver": "1"}) }() } func processFile( string, context.Context) error { time.Sleep(1 * time.Second) return nil }