cancel_async_transition.go 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "time"
  6. "github.com/looplab/fsm"
  7. )
  8. func main() {
  9. f := fsm.NewFSM(
  10. "start",
  11. fsm.Events{
  12. {Name: "run", Src: []string{"start"}, Dst: "end"},
  13. },
  14. fsm.Callbacks{
  15. "leave_start": func(_ context.Context, e *fsm.Event) {
  16. e.Async()
  17. },
  18. },
  19. )
  20. err := f.Event(context.Background(), "run")
  21. asyncError, ok := err.(fsm.AsyncError)
  22. if !ok {
  23. panic(fmt.Sprintf("expected error to be 'AsyncError', got %v", err))
  24. }
  25. var asyncStateTransitionWasCanceled bool
  26. go func() {
  27. <-asyncError.Ctx.Done()
  28. asyncStateTransitionWasCanceled = true
  29. if asyncError.Ctx.Err() != context.Canceled {
  30. panic(fmt.Sprintf("Expected error to be '%v' but was '%v'", context.Canceled, asyncError.Ctx.Err()))
  31. }
  32. }()
  33. asyncError.CancelTransition()
  34. time.Sleep(20 * time.Millisecond)
  35. if err = f.Transition(); err != nil {
  36. panic(fmt.Sprintf("Error encountered when transitioning: %v", err))
  37. }
  38. if !asyncStateTransitionWasCanceled {
  39. panic("expected async state transition cancelation to have propagated")
  40. }
  41. if f.Current() != "start" {
  42. panic("expected state to be 'start'")
  43. }
  44. fmt.Println("Successfully ran state machine.")
  45. }