Thank you for your comprehensive answer. I think it boils down to: A fatal error should not necessarily have to trigger an interrupt for all kernel operations.
Yes, this is definitely a goal. Libbitcoinkernel should try to be a library, not an application or application framework. It should have a convenient way of cancelling operations and not force everything to use one shutdown variable.
But both the current PR and my branch do already support this. The main difference between the PR and branch is that the PR uses a std::atomic<bool>
object, while the branch uses a SignalInterrupt
object.
Going back to this earlier remark again, you declared the m_interrupt
member in your branch as const
. Do you think it is a bad idea to mutate it from within the chainman to forego a call to StartShutdown
?
It’s not necessarily bad, but it would be nice to avoid it. It would be cleaner if interrupt state cleanly represented whether a cancellation was requested or not, and wasn’t also used to handle the -stopatheight
and -stopafterblockimport
corner cases.
Because of this, I was thinking of suggesting dropping the last commit a6a3c3245303d05917c04460e71790e33241f3b5 from the current PR, and leaving the two StartShutdown()
calls in place for now. I think a better approach than calling StartShutdown()
or calling m_interrupt()
in those cases would be to just return “finished” or “success” status codes. Also in both cases, it would be better if the kernel wasn’t deciding itself whether to return early, but instead asked the application through std::function callbacks. I.e. there could be a std::function callbacks for “I just a new chain tip, should I keep processing or return early?” that would be more general than having hardcoded -stopatheight
logic in the kernel. The third “FailedConnectingBestBlock” shutdown case also seems like it should be returning a real error code to the application and calling fatalErrror, not just sending a shutdown notification.