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
, AsyncWrite
,
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 Guard
s. All
guards must be dropped for shutdown to be considered complete. Guards can be created in three ways:
Swansong::guard
returns a standaloneGuard
that 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 aGuard
into a closure or async task that handle an individual request.Swansong::guarded
returns aGuarded
wrapper type provides transparent implementations of various traits likeFuture
andStream
, as well asDeref
ing to the wrapped type. This is identical to moving aGuard
into 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::guarded
allows 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§
- The presence of a Guard delays shutdown.
- Guarded is a convenient way to attach a
Guard
to another type. - A wrapper type that implements Stream when wrapping a [
Stream
] and [Future
] when wrapping a Future - 🦢 Shutdown manager
Enums§
- enum that represents the current status of this
Swansong
.