Expand description
§🦢 A graceful shutdown
§How this crate works
Each Swansong represents a functional unit of behavior that needs to coordinate termination. The
primary type Swansong provides the control interface.
To allow Swansong to interrupt/cancel/seal various types, use
Swansong::interrupt. Interrupt<T> has custom implementations of
Future, Stream,
[AsyncRead][futures_io::AsyncRead], [AsyncWrite][futures_io::AsyncWrite],
[AsyncBufRead][futures_io::AsyncBufRead], and Iterator. See further documentation for the
behaviors for each of these types at Interrupt.
Each of the trait implementations will behave normally with a small overhead to check shutdown state
until shutdown has been initiated with Swansong::shut_down. When shutdown has been initiated,
any type inside of an associated Interrupt will be interrupted/canceled/sealed at an appropriate
time.
Swansong graceful shutdown is considered in progress while there are outstanding Guards. All
guards must be dropped for shutdown to be considered complete. Guards can be created in three ways:
Swansong::guardreturns a standaloneGuardthat can be moved into a closure or future, stored in a struct, or otherwise retained temporarily during a block of code that should not be abruptly stopped. For example, a http server might move aGuardinto a closure or async task that handle an individual request.Swansong::guardedreturns aGuardedwrapper type provides transparent implementations of various traits likeFutureandStream, as well asDerefing to the wrapped type. This is identical to moving aGuardinto the wrapped type, but sometimes it’s easier to compose the guard around a named future than to move the guard into the future.Interrupt::guardedallows an Interrupt wrapper to also act as a guard.
§Async Example
let swansong = Swansong::new();
executor::spawn(swansong.interrupt(pending::<()>()).guarded()).detach();
executor::spawn(swansong.guarded(Timer::after(Duration::from_secs(1)))).detach();
swansong.shut_down().await;§Sync example
let swansong = Swansong::new();
thread::spawn({
let guard = swansong.guard();
move || {
let _guard = guard;
thread::sleep(Duration::from_secs(1));
}
});
thread::spawn({
let swansong = swansong.clone();
move || {
for n in swansong.interrupt(iter::repeat_with(|| fastrand::u8(..)))
{
thread::sleep(Duration::from_millis(100));
println!("{n}");
}
}
});
thread::sleep(Duration::from_millis(500));
swansong.shut_down().block();Structs§
- Guard
- The presence of a Guard delays shutdown.
- Guarded
- Guarded is a convenient way to attach a
Guardto another type. - Interrupt
- A wrapper type that implements Stream when wrapping a [
Stream] and [Future] when wrapping a Future - Shutdown
Completion - A
Futurethat will be ready when theSwansonghas been stopped AND all guards are dropped. - Swansong
- 🦢 Shutdown manager
Enums§
- Shutdown
State - enum that represents the current status of this
Swansong.