Ctrl+C handling for a graceful stop

addSignal() doesn't seem to work, which is probably why it was commented
out. I'm using setControlCHook() instead, moved at an earlier point in the
start-up process, but its handler can only change global variables, so I
had to make "nimbus" global.
This commit is contained in:
Ștefan Talpalaru 2019-07-10 23:23:11 +02:00
parent b2680fbee7
commit 06ab21e8c5
No known key found for this signature in database
GPG Key ID: CBF7934204F1B6F9
1 changed files with 30 additions and 22 deletions

View File

@ -37,10 +37,21 @@ type
ethNode*: EthereumNode ethNode*: EthereumNode
state*: NimbusState state*: NimbusState
proc start(): NimbusObject = var nimbus: NimbusObject
var nimbus = NimbusObject()
proc start() =
var conf = getConfiguration() var conf = getConfiguration()
nimbus = NimbusObject()
nimbus.state = Starting
## Ctrl+C handling
proc handler() {.noconv.} =
# workaround for https://github.com/nim-lang/Nim/issues/4057
setupForeignThreadGc()
nimbus.state = Stopping
setControlCHook(handler)
## logging ## logging
setLogLevel(conf.debug.logLevel) setLogLevel(conf.debug.logLevel)
if len(conf.debug.logFile) != 0: if len(conf.debug.logFile) != 0:
@ -117,10 +128,10 @@ proc start(): NimbusObject =
setupDebugRpc(chainDB, nimbus.rpcServer) setupDebugRpc(chainDB, nimbus.rpcServer)
## Starting servers ## Starting servers
nimbus.state = Starting
if RpcFlags.Enabled in conf.rpc.flags: if RpcFlags.Enabled in conf.rpc.flags:
nimbus.rpcServer.rpc("admin_quit") do() -> string: nimbus.rpcServer.rpc("admin_quit") do() -> string:
nimbus.state = Stopping {.gcsafe.}:
nimbus.state = Stopping
result = "EXITING" result = "EXITING"
nimbus.rpcServer.start() nimbus.rpcServer.start()
@ -147,22 +158,18 @@ proc start(): NimbusObject =
if status != syncSuccess: if status != syncSuccess:
debug "Block sync failed: ", status debug "Block sync failed: ", status
nimbus.state = Running if nimbus.state == Starting:
result = nimbus # it might have been set to "Stopping" with Ctrl+C
nimbus.state = Running
proc stop*(nimbus: NimbusObject) {.async.} = proc stop*() {.async.} =
trace "Graceful shutdown" trace "Graceful shutdown"
nimbus.rpcServer.stop() var conf = getConfiguration()
if RpcFlags.Enabled in conf.rpc.flags:
nimbus.rpcServer.stop()
proc process*(nimbus: NimbusObject) = proc process*() =
if nimbus.state == Running: if nimbus.state == Running:
when not defined(windows):
proc signalBreak(udata: pointer) =
nimbus.state = Stopping
# Adding SIGINT, SIGTERM handlers
# discard addSignal(SIGINT, signalBreak)
# discard addSignal(SIGTERM, signalBreak)
# Main loop # Main loop
while nimbus.state == Running: while nimbus.state == Running:
try: try:
@ -172,16 +179,16 @@ proc process*(nimbus: NimbusObject) =
exc = getCurrentException().name, exc = getCurrentException().name,
err = getCurrentExceptionMsg() err = getCurrentExceptionMsg()
# Stop loop # Stop loop
waitFor nimbus.stop() waitFor stop()
when isMainModule: when isMainModule:
var message: string var message: string
## Pring Nimbus header ## Print Nimbus header
echo NimbusHeader echo NimbusHeader
## show logs on stdout until we get the user's logging choice ## Show logs on stdout until we get the user's logging choice
discard defaultChroniclesStream.output.open(stdout) discard defaultChroniclesStream.output.open(stdout)
## Processing command line arguments ## Processing command line arguments
@ -193,5 +200,6 @@ when isMainModule:
echo message echo message
quit(QuitSuccess) quit(QuitSuccess)
var nimbus = start() start()
nimbus.process() process()