82 lines
2.2 KiB
Nim
Raw Normal View History

2025-02-11 15:03:56 +01:00
import pkg/chronos
import pkg/chronicles
import pkg/datastore
import pkg/datastore/typedds
import pkg/questionable
import pkg/questionable/results
import std/sets
import ../state
import ../types
import ../component
import ../utils/asyncdataevent
2025-02-12 15:16:59 +01:00
import ../services/metrics
2025-02-11 15:03:56 +01:00
logScope:
topics = "todolist"
type TodoList* = ref object of Component
nids: seq[Nid]
state: State
subNew: AsyncDataEventSubscription
subRev: AsyncDataEventSubscription
2025-02-11 15:03:56 +01:00
emptySignal: ?Future[void]
2025-02-12 15:16:59 +01:00
metrics: Metrics
2025-02-11 15:03:56 +01:00
proc addNodes(t: TodoList, nids: seq[Nid]) =
for nid in nids:
if nid notin t.nids:
t.nids.add(nid)
2025-02-11 15:03:56 +01:00
2025-02-12 15:16:59 +01:00
t.metrics.setTodoNodes(t.nids.len)
2025-02-11 15:03:56 +01:00
if s =? t.emptySignal:
trace "nodes added, resuming...", nodes = nids.len
2025-02-11 15:03:56 +01:00
s.complete()
t.emptySignal = Future[void].none
2025-02-12 13:25:37 +01:00
method pop*(t: TodoList): Future[?!Nid] {.async: (raises: []), base.} =
2025-02-11 15:03:56 +01:00
if t.nids.len < 1:
trace "list is empty. Waiting for new items..."
2025-02-11 15:03:56 +01:00
let signal = newFuture[void]("list.emptySignal")
t.emptySignal = some(signal)
2025-02-12 13:25:37 +01:00
try:
2025-02-12 14:12:21 +01:00
await signal.wait(InfiniteDuration)
2025-02-12 13:25:37 +01:00
except CatchableError as exc:
return failure(exc.msg)
2025-02-11 15:03:56 +01:00
if t.nids.len < 1:
return failure("TodoList is empty.")
let item = t.nids[0]
t.nids.del(0)
t.metrics.setTodoNodes(t.nids.len)
2025-02-11 15:03:56 +01:00
return success(item)
2025-06-02 14:30:28 +02:00
method awake*(t: TodoList): Future[?!void] {.async: (raises: [CancelledError]).} =
info "initializing..."
2025-02-11 15:03:56 +01:00
2025-06-02 16:16:41 +02:00
proc onNewNodes(
nids: seq[Nid]
): Future[?!void] {.async: (raises: [CancelledError]).} =
2025-02-11 15:03:56 +01:00
t.addNodes(nids)
return success()
t.subNew = t.state.events.newNodesDiscovered.subscribe(onNewNodes)
t.subRev = t.state.events.nodesToRevisit.subscribe(onNewNodes)
2025-02-11 15:03:56 +01:00
return success()
2025-06-02 14:30:28 +02:00
method stop*(t: TodoList): Future[?!void] {.async: (raises: [CancelledError]).} =
2025-02-11 15:03:56 +01:00
await t.state.events.newNodesDiscovered.unsubscribe(t.subNew)
await t.state.events.nodesToRevisit.unsubscribe(t.subRev)
2025-02-11 15:03:56 +01:00
return success()
2025-02-12 15:16:59 +01:00
proc new*(_: type TodoList, state: State, metrics: Metrics): TodoList =
TodoList(
nids: newSeq[Nid](), state: state, emptySignal: Future[void].none, metrics: metrics
)
2025-02-11 15:03:56 +01:00
2025-02-12 15:16:59 +01:00
proc createTodoList*(state: State, metrics: Metrics): TodoList =
TodoList.new(state, metrics)