mirror of
https://github.com/codex-storage/nim-codex.git
synced 2025-02-16 14:57:54 +00:00
[statemachine] states and events should not raise errors
They would crash the scheduler loop.
This commit is contained in:
parent
f6b534f1e1
commit
50130c33f5
@ -1,5 +1,6 @@
|
||||
import pkg/questionable
|
||||
import pkg/chronos
|
||||
import pkg/upraises
|
||||
|
||||
template makeStateMachine*(MachineType, StateType) =
|
||||
|
||||
@ -10,7 +11,7 @@ template makeStateMachine*(MachineType, StateType) =
|
||||
scheduled: AsyncQueue[Event]
|
||||
scheduling: Future[void]
|
||||
StateType* = ref object of RootObj
|
||||
Event = proc(state: StateType): ?StateType {.gcsafe.}
|
||||
Event = proc(state: StateType): ?StateType {.gcsafe, upraises:[].}
|
||||
|
||||
proc transition(_: type Event, previous, next: StateType): Event =
|
||||
return proc (state: StateType): ?StateType =
|
||||
@ -20,7 +21,7 @@ template makeStateMachine*(MachineType, StateType) =
|
||||
proc schedule*(machine: MachineType, event: Event) =
|
||||
machine.scheduled.putNoWait(event)
|
||||
|
||||
method run*(state: StateType): Future[?StateType] {.base.} =
|
||||
method run*(state: StateType): Future[?StateType] {.base, upraises:[].} =
|
||||
discard
|
||||
|
||||
proc run(machine: MachineType, state: StateType) {.async.} =
|
||||
|
@ -1,7 +1,7 @@
|
||||
import std/sugar
|
||||
import pkg/asynctest
|
||||
import pkg/questionable
|
||||
import pkg/chronos
|
||||
import pkg/upraises
|
||||
import codex/utils/asyncstatemachine
|
||||
import ../helpers/eventually
|
||||
|
||||
@ -14,7 +14,7 @@ type
|
||||
|
||||
var runs, cancellations = [0, 0, 0]
|
||||
|
||||
method onMoveToNextStateEvent*(state: State): ?State {.base.} =
|
||||
method onMoveToNextStateEvent*(state: State): ?State {.base, upraises:[].} =
|
||||
discard
|
||||
|
||||
method run(state: State1): Future[?State] {.async.} =
|
||||
@ -41,6 +41,9 @@ suite "async state machines":
|
||||
var machine: Machine
|
||||
var state1, state2: State
|
||||
|
||||
proc moveToNextStateEvent(state: State): ?State =
|
||||
state.onMoveToNextStateEvent()
|
||||
|
||||
setup:
|
||||
runs = [0, 0, 0]
|
||||
cancellations = [0, 0, 0]
|
||||
@ -58,25 +61,25 @@ suite "async state machines":
|
||||
|
||||
test "state2 moves to state3 on event":
|
||||
machine.start(state2)
|
||||
machine.schedule(state {.gcsafe.} => state.onMoveToNextStateEvent())
|
||||
machine.schedule(moveToNextStateEvent)
|
||||
check eventually runs == [0, 1, 1]
|
||||
|
||||
test "state transition will cancel the running state":
|
||||
machine.start(state2)
|
||||
machine.schedule(state {.gcsafe.} => state.onMoveToNextStateEvent())
|
||||
machine.schedule(moveToNextStateEvent)
|
||||
check eventually cancellations == [0, 1, 0]
|
||||
|
||||
test "scheduled events are handled one after the other":
|
||||
machine.start(state2)
|
||||
machine.schedule(state {.gcsafe.} => state.onMoveToNextStateEvent())
|
||||
machine.schedule(state {.gcsafe.} => state.onMoveToNextStateEvent())
|
||||
machine.schedule(moveToNextStateEvent)
|
||||
machine.schedule(moveToNextStateEvent)
|
||||
check eventually runs == [1, 2, 1]
|
||||
|
||||
test "stops scheduling and current state":
|
||||
machine.start(state2)
|
||||
await sleepAsync(1.millis)
|
||||
machine.stop()
|
||||
machine.schedule(state {.gcsafe.} => state.onMoveToNextStateEvent())
|
||||
machine.schedule(moveToNextStateEvent)
|
||||
await sleepAsync(1.millis)
|
||||
check runs == [0, 1, 0]
|
||||
check cancellations == [0, 1, 0]
|
||||
|
Loading…
x
Reference in New Issue
Block a user