From c1b0c30cc0a1adb68fb34f75991cb70577ecdfc2 Mon Sep 17 00:00:00 2001 From: ThatBen Date: Fri, 21 Mar 2025 13:04:10 +0100 Subject: [PATCH] splits awake and start component methods --- codexcrawler/application.nim | 8 +++++++- codexcrawler/component.nim | 15 +++++++++++---- codexcrawler/components/chaincrawler.nim | 6 +++--- codexcrawler/components/chainmetrics.nim | 9 ++++----- codexcrawler/components/dhtcrawler.nim | 3 --- codexcrawler/components/dhtmetrics.nim | 11 ++++++----- codexcrawler/components/requeststore.nim | 7 ------- codexcrawler/components/timetracker.nim | 3 --- codexcrawler/components/todolist.nim | 8 ++++---- codexcrawler/services/marketplace.nim | 9 +++------ .../codexcrawler/components/testchaincrawler.nim | 6 ------ .../codexcrawler/components/testchainmetrics.nim | 2 -- tests/codexcrawler/components/testdhtcrawler.nim | 3 --- tests/codexcrawler/components/testdhtmetrics.nim | 2 +- tests/codexcrawler/components/testnodestore.nim | 1 - .../codexcrawler/components/testrequeststore.nim | 3 --- tests/codexcrawler/components/testtimetracker.nim | 2 -- tests/codexcrawler/components/testtodolist.nim | 3 +-- tests/codexcrawler/mocks/mockdht.nim | 6 ------ tests/codexcrawler/mocks/mocknodestore.nim | 6 ------ tests/codexcrawler/mocks/mocktodolist.nim | 6 ------ 21 files changed, 40 insertions(+), 79 deletions(-) diff --git a/codexcrawler/application.nim b/codexcrawler/application.nim index 0f7f73c..e5a0d07 100644 --- a/codexcrawler/application.nim +++ b/codexcrawler/application.nim @@ -36,9 +36,15 @@ proc initializeApp(app: Application, config: Config): Future[?!void] {.async.} = return failure(err) app.components = components + for c in components: + if err =? (await c.awake()).errorOption: + error "Failed during component awake", err = err.msg + return failure(err) + for c in components: if err =? (await c.start()).errorOption: - error "Failed to start component", err = err.msg + error "Failed during component start", err = err.msg + return failure(err) return success() diff --git a/codexcrawler/component.nim b/codexcrawler/component.nim index f36b0a2..ce1517b 100644 --- a/codexcrawler/component.nim +++ b/codexcrawler/component.nim @@ -1,12 +1,19 @@ import pkg/chronos import pkg/questionable/results -import ./state - type Component* = ref object of RootObj +method awake*(c: Component): Future[?!void] {.async, base.} = + # Awake is called on all components in an unspecified order. + # Use this method to subscribe/connect to other components. + return success() + method start*(c: Component): Future[?!void] {.async, base.} = - raiseAssert("call to abstract method: component.start") + # Start is called on all components in an unspecified order. + # Is is guaranteed that all components have already successfulled handled 'awake'. + # Use this method to begin the work of this component. + return success() method stop*(c: Component): Future[?!void] {.async, base.} = - raiseAssert("call to abstract method: component.stop") + # Use this method to stop, unsubscribe, and clean up any resources. + return success() diff --git a/codexcrawler/components/chaincrawler.nim b/codexcrawler/components/chaincrawler.nim index 70941fd..b29e9f8 100644 --- a/codexcrawler/components/chaincrawler.nim +++ b/codexcrawler/components/chaincrawler.nim @@ -25,13 +25,13 @@ method start*(c: ChainCrawler): Future[?!void] {.async.} = proc onRequest(rid: Rid): Future[?!void] {.async: (raises: []).} = return await c.onNewRequest(rid) + # Normally subscriptions must be done in awake. + # Marketplace is a little different: It uses awake to set up its connections. + # And so it can't handle subscribes until we're in 'start'. ?await c.marketplace.subscribeToNewRequests(onRequest) ?await c.marketplace.iteratePastNewRequestEvents(onRequest) return success() -method stop*(c: ChainCrawler): Future[?!void] {.async.} = - return success() - proc new*( T: type ChainCrawler, state: State, diff --git a/codexcrawler/components/chainmetrics.nim b/codexcrawler/components/chainmetrics.nim index 80c6d3b..b23041c 100644 --- a/codexcrawler/components/chainmetrics.nim +++ b/codexcrawler/components/chainmetrics.nim @@ -71,15 +71,14 @@ method start*(c: ChainMetrics): Future[?!void] {.async.} = return success() -method stop*(c: ChainMetrics): Future[?!void] {.async.} = - return success() - proc new*( T: type ChainMetrics, state: State, metrics: Metrics, store: RequestStore, marketplace: MarketplaceService, - clock: Clock + clock: Clock, ): ChainMetrics = - ChainMetrics(state: state, metrics: metrics, store: store, marketplace: marketplace, clock: clock) + ChainMetrics( + state: state, metrics: metrics, store: store, marketplace: marketplace, clock: clock + ) diff --git a/codexcrawler/components/dhtcrawler.nim b/codexcrawler/components/dhtcrawler.nim index 5fde23e..0c594b2 100644 --- a/codexcrawler/components/dhtcrawler.nim +++ b/codexcrawler/components/dhtcrawler.nim @@ -57,8 +57,5 @@ method start*(c: DhtCrawler): Future[?!void] {.async.} = return success() -method stop*(c: DhtCrawler): Future[?!void] {.async.} = - return success() - proc new*(T: type DhtCrawler, state: State, dht: Dht, todo: TodoList): DhtCrawler = DhtCrawler(state: state, dht: dht, todo: todo) diff --git a/codexcrawler/components/dhtmetrics.nim b/codexcrawler/components/dhtmetrics.nim index a8d0c74..374e169 100644 --- a/codexcrawler/components/dhtmetrics.nim +++ b/codexcrawler/components/dhtmetrics.nim @@ -45,11 +45,7 @@ proc handleDeleteEvent(d: DhtMetrics, nids: seq[Nid]): Future[?!void] {.async.} d.updateMetrics() return success() -method start*(d: DhtMetrics): Future[?!void] {.async.} = - info "starting..." - ?await d.ok.load() - ?await d.nok.load() - +method awake*(d: DhtMetrics): Future[?!void] {.async.} = proc onCheck(event: DhtNodeCheckEventData): Future[?!void] {.async.} = await d.handleCheckEvent(event) @@ -58,7 +54,12 @@ method start*(d: DhtMetrics): Future[?!void] {.async.} = d.subCheck = d.state.events.dhtNodeCheck.subscribe(onCheck) d.subDel = d.state.events.nodesDeleted.subscribe(onDelete) + return success() +method start*(d: DhtMetrics): Future[?!void] {.async.} = + info "starting..." + ?await d.ok.load() + ?await d.nok.load() return success() method stop*(d: DhtMetrics): Future[?!void] {.async.} = diff --git a/codexcrawler/components/requeststore.nim b/codexcrawler/components/requeststore.nim index e4f18b6..130a6e5 100644 --- a/codexcrawler/components/requeststore.nim +++ b/codexcrawler/components/requeststore.nim @@ -117,13 +117,6 @@ method iterateAll*( return failure(exc.msg) return success() -method start*(s: RequestStore): Future[?!void] {.async.} = - info "starting..." - return success() - -method stop*(s: RequestStore): Future[?!void] {.async.} = - return success() - proc new*( T: type RequestStore, state: State, store: TypedDatastore, clock: Clock ): RequestStore = diff --git a/codexcrawler/components/timetracker.nim b/codexcrawler/components/timetracker.nim index a4217cb..2683b0a 100644 --- a/codexcrawler/components/timetracker.nim +++ b/codexcrawler/components/timetracker.nim @@ -71,9 +71,6 @@ method start*(t: TimeTracker): Future[?!void] {.async.} = await t.state.whileRunning(onRoutingTable, 30.minutes) return success() -method stop*(t: TimeTracker): Future[?!void] {.async.} = - return success() - proc new*( T: type TimeTracker, state: State, nodestore: NodeStore, dht: Dht, clock: Clock ): TimeTracker = diff --git a/codexcrawler/components/todolist.nim b/codexcrawler/components/todolist.nim index e271f1e..33144ae 100644 --- a/codexcrawler/components/todolist.nim +++ b/codexcrawler/components/todolist.nim @@ -32,13 +32,13 @@ proc addNodes(t: TodoList, nids: seq[Nid]) = t.metrics.setTodoNodes(t.nids.len) if s =? t.emptySignal: - trace "Nodes added, resuming...", nodes = nids.len + trace "nodes added, resuming...", nodes = nids.len s.complete() t.emptySignal = Future[void].none method pop*(t: TodoList): Future[?!Nid] {.async: (raises: []), base.} = if t.nids.len < 1: - trace "List is empty. Waiting for new items..." + trace "list is empty. Waiting for new items..." let signal = newFuture[void]("list.emptySignal") t.emptySignal = some(signal) try: @@ -54,8 +54,8 @@ method pop*(t: TodoList): Future[?!Nid] {.async: (raises: []), base.} = return success(item) -method start*(t: TodoList): Future[?!void] {.async.} = - info "Starting TodoList..." +method awake*(t: TodoList): Future[?!void] {.async.} = + info "initializing..." proc onNewNodes(nids: seq[Nid]): Future[?!void] {.async.} = t.addNodes(nids) diff --git a/codexcrawler/services/marketplace.nim b/codexcrawler/services/marketplace.nim index 4a84d1a..494ff4c 100644 --- a/codexcrawler/services/marketplace.nim +++ b/codexcrawler/services/marketplace.nim @@ -53,11 +53,11 @@ method subscribeToNewRequests*( if market =? m.market: try: discard await market.subscribeRequests(onRequest) + return success() except CatchableError as exc: return failure(exc.msg) else: notStarted() - return success() method iteratePastNewRequestEvents*( m: MarketplaceService, onNewRequest: OnNewRequest @@ -73,6 +73,7 @@ method iteratePastNewRequestEvents*( for request in requests: if error =? (await onNewRequest(Rid(request.requestId))).errorOption: return failure(error.msg) + return success() except CatchableError as exc: return failure(exc.msg) else: @@ -95,17 +96,13 @@ method getRequestInfo*( else: notStarted() -method start*(m: MarketplaceService): Future[?!void] {.async.} = +method awake*(m: MarketplaceService): Future[?!void] {.async.} = let provider = JsonRpcProvider.new(m.state.config.ethProvider) without marketplaceAddress =? Address.init(m.state.config.marketplaceAddress): return failure("Invalid MarketplaceAddress provided") let marketplace = Marketplace.new(marketplaceAddress, provider) m.market = some(OnChainMarket.new(marketplace)) - - return success() - -method stop*(m: MarketplaceService): Future[?!void] {.async.} = return success() proc new(T: type MarketplaceService, state: State, clock: Clock): MarketplaceService = diff --git a/tests/codexcrawler/components/testchaincrawler.nim b/tests/codexcrawler/components/testchaincrawler.nim index cdd74f3..172b2b3 100644 --- a/tests/codexcrawler/components/testchaincrawler.nim +++ b/tests/codexcrawler/components/testchaincrawler.nim @@ -27,17 +27,11 @@ suite "ChainCrawler": marketplace = createMockMarketplaceService() crawler = ChainCrawler.new(state, store, marketplace) - (await crawler.start()).tryGet() teardown: - (await crawler.stop()).tryGet() state.checkAllUnsubscribed() - # subscribe to newrequests - # iterate past requests on start-up - # push them into the request store - test "start should subscribe to new requests": check: marketplace.subNewRequestsCallback.isSome() diff --git a/tests/codexcrawler/components/testchainmetrics.nim b/tests/codexcrawler/components/testchainmetrics.nim index eaae1d9..1098f45 100644 --- a/tests/codexcrawler/components/testchainmetrics.nim +++ b/tests/codexcrawler/components/testchainmetrics.nim @@ -31,11 +31,9 @@ suite "ChainMetrics": clock = createMockClock() chain = ChainMetrics.new(state, metrics, store, marketplace, clock) - (await chain.start()).tryGet() teardown: - (await chain.stop()).tryGet() state.checkAllUnsubscribed() proc onStep() {.async.} = diff --git a/tests/codexcrawler/components/testdhtcrawler.nim b/tests/codexcrawler/components/testdhtcrawler.nim index def5ddc..4ae4d21 100644 --- a/tests/codexcrawler/components/testdhtcrawler.nim +++ b/tests/codexcrawler/components/testdhtcrawler.nim @@ -30,11 +30,9 @@ suite "DhtCrawler": dht = createMockDht() crawler = DhtCrawler.new(state, dht, todo) - (await crawler.start()).tryGet() teardown: - (await crawler.stop()).tryGet() state.checkAllUnsubscribed() proc onStep() {.async.} = @@ -57,7 +55,6 @@ suite "DhtCrawler": test "onStep is not activated when config.dhtEnable is false": # Recreate crawler, reset mockstate: - (await crawler.stop()).tryGet() state.steppers = @[] # disable DHT: state.config.dhtEnable = false diff --git a/tests/codexcrawler/components/testdhtmetrics.nim b/tests/codexcrawler/components/testdhtmetrics.nim index 6475d05..98c48ab 100644 --- a/tests/codexcrawler/components/testdhtmetrics.nim +++ b/tests/codexcrawler/components/testdhtmetrics.nim @@ -28,7 +28,7 @@ suite "DhtMetrics": metrics = createMockMetrics() dhtmetrics = DhtMetrics.new(state, okList, nokList, metrics) - + (await dhtmetrics.awake()).tryGet() (await dhtmetrics.start()).tryGet() teardown: diff --git a/tests/codexcrawler/components/testnodestore.nim b/tests/codexcrawler/components/testnodestore.nim index f2a3a17..9ae8698 100644 --- a/tests/codexcrawler/components/testnodestore.nim +++ b/tests/codexcrawler/components/testnodestore.nim @@ -30,7 +30,6 @@ suite "Nodestore": clock = createMockClock() store = NodeStore.new(state, ds, clock) - (await store.start()).tryGet() teardown: diff --git a/tests/codexcrawler/components/testrequeststore.nim b/tests/codexcrawler/components/testrequeststore.nim index 93858e9..c3202f6 100644 --- a/tests/codexcrawler/components/testrequeststore.nim +++ b/tests/codexcrawler/components/testrequeststore.nim @@ -30,10 +30,7 @@ suite "Requeststore": store = RequestStore.new(state, ds, clock) - (await store.start()).tryGet() - teardown: - (await store.stop()).tryGet() (await ds.close()).tryGet() state.checkAllUnsubscribed() removeDir(dsPath) diff --git a/tests/codexcrawler/components/testtimetracker.nim b/tests/codexcrawler/components/testtimetracker.nim index 0c9b4cd..1e405ad 100644 --- a/tests/codexcrawler/components/testtimetracker.nim +++ b/tests/codexcrawler/components/testtimetracker.nim @@ -47,11 +47,9 @@ suite "TimeTracker": state.config.expiryDelayMins = 22 time = TimeTracker.new(state, store, dht, clock) - (await time.start()).tryGet() teardown: - (await time.stop()).tryGet() await state.events.nodesToRevisit.unsubscribe(sub) state.checkAllUnsubscribed() diff --git a/tests/codexcrawler/components/testtodolist.nim b/tests/codexcrawler/components/testtodolist.nim index cca8512..b861f7b 100644 --- a/tests/codexcrawler/components/testtodolist.nim +++ b/tests/codexcrawler/components/testtodolist.nim @@ -23,8 +23,7 @@ suite "TodoList": metrics = createMockMetrics() todo = TodoList.new(state, metrics) - - (await todo.start()).tryGet() + (await todo.awake()).tryGet() teardown: (await todo.stop()).tryGet() diff --git a/tests/codexcrawler/mocks/mockdht.nim b/tests/codexcrawler/mocks/mockdht.nim index 4c12f33..59c6d0b 100644 --- a/tests/codexcrawler/mocks/mockdht.nim +++ b/tests/codexcrawler/mocks/mockdht.nim @@ -18,11 +18,5 @@ method getNeighbors*( d.getNeighborsArg = some(target) return d.getNeighborsReturn -method start*(d: MockDht): Future[?!void] {.async.} = - return success() - -method stop*(d: MockDht): Future[?!void] {.async.} = - return success() - proc createMockDht*(): MockDht = MockDht() diff --git a/tests/codexcrawler/mocks/mocknodestore.nim b/tests/codexcrawler/mocks/mocknodestore.nim index ed78f31..d596565 100644 --- a/tests/codexcrawler/mocks/mocknodestore.nim +++ b/tests/codexcrawler/mocks/mocknodestore.nim @@ -22,11 +22,5 @@ method deleteEntries*( s.nodesToDelete = nids return success() -method start*(s: MockNodeStore): Future[?!void] {.async.} = - return success() - -method stop*(s: MockNodeStore): Future[?!void] {.async.} = - return success() - proc createMockNodeStore*(): MockNodeStore = MockNodeStore(nodesToIterate: newSeq[NodeEntry](), nodesToDelete: newSeq[Nid]()) diff --git a/tests/codexcrawler/mocks/mocktodolist.nim b/tests/codexcrawler/mocks/mocktodolist.nim index 1417ae4..e7b11cd 100644 --- a/tests/codexcrawler/mocks/mocktodolist.nim +++ b/tests/codexcrawler/mocks/mocktodolist.nim @@ -10,11 +10,5 @@ type MockTodoList* = ref object of TodoList method pop*(t: MockTodoList): Future[?!Nid] {.async: (raises: []).} = return t.popReturn -method start*(t: MockTodoList): Future[?!void] {.async.} = - return success() - -method stop*(t: MockTodoList): Future[?!void] {.async.} = - return success() - proc createMockTodoList*(): MockTodoList = MockTodoList()