beacon_node: graceful shutdown (#1033)

* beacon_node: graceful shutdown

* separate BeaconNodeStatus and BeaconNode instances
This commit is contained in:
Ștefan Talpalaru 2020-05-19 20:57:35 +02:00 committed by GitHub
parent f4d38611ef
commit c4462af4ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 39 deletions

View File

@ -36,6 +36,13 @@ type
RpcServer* = RpcHttpServer
KeyPair = eth2_network.KeyPair
# "state" is already taken by BeaconState
BeaconNodeStatus* = enum
Starting, Running, Stopping
# this needs to be global, so it can be set in the Ctrl+C signal handler
var status = BeaconNodeStatus.Starting
template init(T: type RpcHttpServer, ip: IpAddress, port: Port): T =
newRpcHttpServer([initTAddress(ip, port)])
@ -722,7 +729,16 @@ proc installAttestationHandlers(node: BeaconNode) =
waitFor allFutures(attestationSubscriptions)
proc stop*(node: BeaconNode) =
status = BeaconNodeStatus.Stopping
info "Graceful shutdown"
waitFor node.network.stop()
proc run*(node: BeaconNode) =
if status == BeaconNodeStatus.Starting:
# it might have been set to "Stopping" with Ctrl+C
status = BeaconNodeStatus.Running
if node.rpcServer != nil:
node.rpcServer.installRpcHandlers(node)
node.rpcServer.start()
@ -759,7 +775,15 @@ proc run*(node: BeaconNode) =
node.syncLoop = runSyncLoop(node)
runForever()
# main event loop
while status == BeaconNodeStatus.Running:
try:
poll()
except CatchableError as e:
debug "Exception in poll()", exc = e.name, err = e.msg
# time to say goodbye
node.stop()
var gPidFile: string
proc createPidFile(filename: string) =
@ -955,15 +979,6 @@ programMain:
stderr.write "Invalid value for --log-level. " & err.msg
quit 1
## Ctrl+C handling
proc controlCHandler() {.noconv.} =
when defined(windows):
# workaround for https://github.com/nim-lang/Nim/issues/4057
setupForeignThreadGc()
debug "Shutting down after having received SIGINT"
quit(QuitFailure)
setControlCHook(controlCHandler)
case config.cmd
of createTestnet:
var deposits: seq[Deposit]
@ -1043,6 +1058,16 @@ programMain:
createPidFile(config.dataDir.string / "beacon_node.pid")
var node = waitFor BeaconNode.init(config)
## Ctrl+C handling
proc controlCHandler() {.noconv.} =
when defined(windows):
# workaround for https://github.com/nim-lang/Nim/issues/4057
setupForeignThreadGc()
info "Shutting down after having received SIGINT"
status = BeaconNodeStatus.Stopping
setControlCHook(controlCHandler)
when hasPrompt:
initPrompt(node)

View File

@ -718,6 +718,13 @@ proc start*(node: Eth2Node) {.async.} =
node.discoveryLoop = node.runDiscoveryLoop()
traceAsyncErrors node.discoveryLoop
proc stop*(node: Eth2Node) {.async.} =
# ignore errors in futures, since we're shutting down
await allFutures(@[
node.discovery.closeWait(),
node.switch.stop(),
])
proc init*(T: type Peer, network: Eth2Node, info: PeerInfo): Peer =
new result
result.info = info

View File

@ -442,6 +442,7 @@ proc getGenesis*(m: MainchainMonitor): Future[BeaconStateRef] {.async.} =
if m.genesisState != nil:
return m.genesisState
else:
result = new BeaconStateRef # make the compiler happy
raiseAssert "Unreachable code"
method getBlockByHash*(p: Web3DataProviderRef, hash: BlockHash): Future[BlockObject] =

View File

@ -110,7 +110,7 @@ if [[ "$USE_TMUX" != "no" ]]; then
$TMUX select-window -t "${TMUX_SESSION_NAME}:sim"
fi
$MAKE -j3 NIMFLAGS="$CUSTOM_NIMFLAGS $DEFS" LOG_LEVEL="${LOG_LEVEL:-DEBUG}" beacon_node process_dashboard deposit_contract
$MAKE -j3 --no-print-directory NIMFLAGS="$CUSTOM_NIMFLAGS $DEFS" LOG_LEVEL="${LOG_LEVEL:-DEBUG}" beacon_node process_dashboard deposit_contract
if [ ! -f "${LAST_VALIDATOR}" ]; then
if [ "$WEB3_ARG" != "" ]; then