refactor(wallet): implement graceful shutdown of the db #717
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The Problem
When shutting down the application with an
INTsignal (Ctrl-C), the database is not flushed. Nevertheless, it will be automatically flushed when starting the application again, but this is not desirable since we are forcing users to always start the application just to persist pending changes that couldn't be applied when the application stopped.If we flush the database before shutting down, we receive a
pure virtual method calledin some cases. The error means we must drop the database handle before static destruction kicks in.Solution to
1The solution here is very simple, when handling the shutdown signal (
impl Handler<Shutdown> for Controller) we issue aStopmessage to the App actor, and in turn this one sends aFlushmessage to the Storage actor.Solution to
2Solution
1is very simple, but after we implement it we find ourselves with issue2. The reason is this line in Storage's actor builder:The reasons for doing this are:
SyncArbiter::startreceives has typeFn() -> impl ActorArcto guard the access to the db instanceArcis captured by the closure2The solution I've come with is to keep the db ownership inside the App actor itself, and whenever a storage-related message is sent to the Storage actor, we send with it a reference to the db. The difference with the previous solution is that now the references sent to the Storage actor are only "alive" during the message handling, and not for the entire lifetime of the Storage's sync-arbiter thread.