57 lines
1.7 KiB
Nim
Raw Normal View History

2025-02-10 14:49:30 +01:00
import pkg/chronos
2025-02-11 15:33:40 +01:00
import pkg/chronicles
2025-02-10 14:49:30 +01:00
import pkg/questionable/results
import ./config
2025-02-10 15:34:41 +01:00
import ./utils/asyncdataevent
import ./types
2025-02-10 14:49:30 +01:00
2025-02-11 15:33:40 +01:00
logScope:
topics = "state"
2025-02-10 14:49:30 +01:00
type
2025-02-11 16:31:23 +01:00
OnStep* = proc(): Future[?!void] {.async: (raises: []), gcsafe.}
2025-02-10 15:34:41 +01:00
DhtNodeCheckEventData* = object
id*: Nid
isOk*: bool
Events* = ref object
nodesFound*: AsyncDataEvent[seq[Nid]]
newNodesDiscovered*: AsyncDataEvent[seq[Nid]]
dhtNodeCheck*: AsyncDataEvent[DhtNodeCheckEventData]
nodesToRevisit*: AsyncDataEvent[seq[Nid]]
nodesDeleted*: AsyncDataEvent[seq[Nid]]
2025-02-10 15:34:41 +01:00
2025-02-11 15:33:40 +01:00
ApplicationStatus* {.pure.} = enum
Stopped
Stopping
Running
2025-02-11 10:54:58 +01:00
State* = ref object of RootObj
2025-02-11 15:33:40 +01:00
status*: ApplicationStatus
2025-02-10 14:49:30 +01:00
config*: Config
2025-02-10 16:24:54 +01:00
events*: Events
2025-02-10 14:49:30 +01:00
2025-06-02 16:16:41 +02:00
proc delayedWorkerStart(
s: State, step: OnStep, delay: Duration
) {.async: (raises: [CancelledError]).} =
await sleepAsync(1.seconds)
2025-02-12 13:50:12 +01:00
2025-06-02 14:30:28 +02:00
proc worker(): Future[void] {.async: (raises: [CancelledError]).} =
2025-02-11 15:33:40 +01:00
while s.status == ApplicationStatus.Running:
if err =? (await step()).errorOption:
error "Failure-result caught in main loop. Stopping...", err = err.msg
s.status = ApplicationStatus.Stopping
await sleepAsync(delay)
asyncSpawn worker()
2025-02-12 13:50:12 +01:00
2025-06-02 16:16:41 +02:00
method whileRunning*(
s: State, step: OnStep, delay: Duration
) {.async: (raises: []), base.} =
2025-02-12 13:50:12 +01:00
# We use a small delay before starting the workers because 'whileRunning' is likely called from
# component 'start' methods, which are executed sequentially in arbitrary order (to prevent temporal coupling).
# Worker steps might start raising events that other components haven't had time to subscribe to yet.
asyncSpawn s.delayedWorkerStart(step, delay)