TIL: Exit handlers
In this post I talk about exit handlers which are mostly used to gracefully shutdown your applications.
Let’s take an example of an application with a thread which flushes something periodically(e.g. every 5 seconds) to some storage (e.g. Redis), and you don’t want to lose data on shutdown i.e. you want to flush the last batch before you shutdown.
How would you go about implementing that?
One way to deal with this is to listen for terminate/kill signals (SIGTERM/SIGKILL) and flush your last batch before you shutdown. It will work, but for that you need to know which kill signal is being sent. In most cases you know it but in some cases you don’t.
To deal with that maybe you will assume some common defaults and add a config option which will allow users to configure kill signal.
Obviously this will work but you will end up writing lots of boilerplate code to handle signals.
Another way to do this is to register an exit handler. Almost all programming languages expose these exit handlers. You register a function to exit handler, and it gets executed on termination of your program. Actual implementation varies for each language.
Here is an example in Ruby
at_exit do
# this code will be executed when the program exits
puts "at_exit called, going to shutdown, kthxbye"
end
Look at docs to know more about exit handlers for your language, here are links for some common languages.
- Ruby - at_exit
- Python3 - atexit
- Python2 - atexit (You should not be using Python2 anyway)
- Rust - at_exit
- C - atexit
- Golang doesn’t implement exit handler see this StackOverflow thread to know why, there is a third party package called goodbye which implements exit handlers.
Fun Fact: I learned about exit handlers when I wrote some code to send monitoring data in background from my application to monitoring service
Tweet me @electron0zero if you have any corrections/suggestions