This crate consists of a convenient macro to specify on shutdown callbacks called on_shutdown!
. It takes code that
should be executed when your program exits (gracefully).
Internally it creates a FnOnce
-closure that gets executed when the context gets dropped, i.e. when
main()
exits. There is also on_shutdown_move!
available in case the FnOnce
-closure needs to capture vars, like an Arc<>
.
In theory this macro can be used everywhere where the context gets dropped. But it has a nice expressive name so that
one exactly knows what it should achieve in code. A good example is the main()
function in an actix-web
-Server. For
example you want to log to a file when the server was shut down.
There is no guarantee that this gets executed during "non-regular" shutdown scenarios, like when
receiving CTRL+C / SIGINT / SIGTERM
. This depends on whether your application properly handles signals and if the
operating system gives your application time before it gets totally killed/stopped.
IMPORTANT: Use this on the top level of your main() or whatever your current runtimes main function is! The code gets executed when the context it lives in gets dropped. This macro can be called multiple times (at least with stable Rust 1.48.0) without problems.
This crate uses the log
crate on the debug
level.
With "runtimes you do not have control over" I mean that for example actix doesn't let you specify shutdown callbacks by itself. In such cases my macro may be a better option.
```rust use simpleonshutdown::{onshutdown, onshutdown_move};
// ... fn main() { on_shutdown!(println!("shutted down"));
// If you need to move a variable into the `FnOnce`-closure
let foobar = Arc::new(AtomicBool::new(false));
on_shutdown_move!({
foobar.store(true, Ordering::Relaxed);
println!("foobar={}", foobar.load(Ordering::Relaxed));
}); } ```
```rust // Not recommended, old way
extern crate simpleonshutdown;
// ... fn main() { on_shutdown!(println!("shutted down")); } ```
See also "example/"-dir in repository!
```rust use actixweb::{get, HttpServer, App, HttpResponse, Responder}; use simpleonshutdown::onshutdown;
async fn get_index() -> impl Responder { HttpResponse::Ok().body("Hello World") }
async fn main() -> std::io::Result<()> { // Important that the returned value of the macro lives through // the whole lifetime of main(). It gets dropped in the end. on_shutdown!({ // the actual code println!("This gets executed during shutdown. Better don't do expensive operations here."); });
HttpServer::new(|| {
App::new()
.service(get_index)
})
.bind(format!("localhost:{}", 8080))?
.run()
.await
} ```
See example/
-directory.
CTRL+C / SIGINT / SIGTERM
SIGINT/SIGTERM
(and other signals) in a proper way to allow a gracefully "non-regular"
shutdown (Actix web framework does this for example)
CTRL+C
will immediately shut down your appexample/src/bin/simple_example_ctrl_c_signal
for
more details.