From 74679e9e2efeb8956132a79bea16728d76a7fe5e Mon Sep 17 00:00:00 2001 From: Giuliano Mega Date: Mon, 11 Mar 2024 09:31:17 -0300 Subject: [PATCH] abort Codex when startup sequence fails (#738) --- codex.nim | 40 ++++++++++++++++++++++++---------------- codex/codex.nim | 6 ------ 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/codex.nim b/codex.nim index f7215db6..a262bbc8 100644 --- a/codex.nim +++ b/codex.nim @@ -80,7 +80,7 @@ when isMainModule: var state: CodexStatus - pendingFuts: seq[Future[void]] + shutdown: Future[void] let keyPath = @@ -93,6 +93,12 @@ when isMainModule: server = CodexServer.new(config, privateKey) ## Ctrl+C handling + proc doShutdown() = + shutdown = server.stop() + state = CodexStatus.Stopping + + notice "Stopping Codex" + proc controlCHandler() {.noconv.} = when defined(windows): # workaround for https://github.com/nim-lang/Nim/issues/4057 @@ -101,10 +107,7 @@ when isMainModule: except Exception as exc: raiseAssert exc.msg # shouldn't happen notice "Shutting down after having received SIGINT" - pendingFuts.add(server.stop()) - state = CodexStatus.Stopping - - notice "Stopping Codex" + doShutdown() try: setControlCHook(controlCHandler) @@ -116,26 +119,31 @@ when isMainModule: proc SIGTERMHandler(signal: cint) {.noconv.} = notice "Shutting down after having received SIGTERM" - pendingFuts.add(server.stop()) - state = CodexStatus.Stopping - - notice "Stopping Codex" + doShutdown() c_signal(ansi_c.SIGTERM, SIGTERMHandler) - pendingFuts.add(server.start()) + try: + waitFor server.start() + except CatchableError as error: + error "Codex failed to start", error = error.msg + # XXX ideally we'd like to issue a stop instead of quitting cold turkey, + # but this would mean we'd have to fix the implementation of all + # services so they won't crash if we attempt to stop them before they + # had a chance to start (currently you'll get a SISGSEV if you try to). + quit QuitFailure state = CodexStatus.Running while state == CodexStatus.Running: # poll chronos chronos.poll() - # wait fot futures to finish - let res = waitFor allFinished(pendingFuts) - state = CodexStatus.Stopped - - if res.anyIt( it.failed ): - error "Codex didn't shutdown correctly" + try: + # signal handlers guarantee that the shutdown Future will + # be assigned before state switches to Stopping + waitFor shutdown + except CatchableError as error: + error "Codex didn't shutdown correctly", error = error.msg quit QuitFailure notice "Exited codex" diff --git a/codex/codex.nim b/codex/codex.nim index c5bcb7b6..637fbca6 100644 --- a/codex/codex.nim +++ b/codex/codex.nim @@ -46,7 +46,6 @@ logScope: type CodexServer* = ref object - runHandle: Future[void] config: CodexConf restServer: RestServerRef codexNode: CodexNodeRef @@ -183,9 +182,6 @@ proc start*(s: CodexServer) {.async.} = await s.codexNode.start() s.restServer.start() - s.runHandle = newFuture[void]("codex.runHandle") - await s.runHandle - proc stop*(s: CodexServer) {.async.} = notice "Stopping codex node" @@ -196,8 +192,6 @@ proc stop*(s: CodexServer) {.async.} = s.repoStore.stop(), s.maintenance.stop()) - s.runHandle.complete() - proc new*( T: type CodexServer, config: CodexConf,