pub struct Swansong { /* private fields */ }Expand description
Implementations§
Source§impl Swansong
impl Swansong
Sourcepub fn with_guard_report() -> Swansong
pub fn with_guard_report() -> Swansong
Construct a new Swansong whose Guards record where and when they were created, for
Swansong::guard_report. Its children do the same.
This is a debugging aid for shutdowns that stall on straggling guards, so it is chosen when the root is created: a report switched on later would miss the guards that already exist. Recording costs an allocation, a clock read and a lock on every guard; without it, creating and dropping a guard costs none of these.
let swansong = Swansong::with_guard_report();
let _guard = swansong.guard();
let report = swansong.guard_report();
assert_eq!(report.entries().len(), 1);
println!("{report}");Sourcepub fn shut_down(&self) -> ShutdownCompletion â
pub fn shut_down(&self) -> ShutdownCompletion â
Initiate graceful shutdown.
This will gracefully stop any associated Interrupts.
This returns a ShutdownCompletion type, which can be blocked on with
ShutdownCompletion::block or awaited as a Future.
Sourcepub fn block_on_shutdown_completion(self)
pub fn block_on_shutdown_completion(self)
Blocks the current thread until graceful shutdown is complete
Do not use this in async contexts. Instead, await the Swansong
Sourcepub fn state(&self) -> ShutdownState
pub fn state(&self) -> ShutdownState
Determine if this Swansong is running, shutting down, or complete.
Sourcepub fn shutting_down(&self) -> ShuttingDown â
pub fn shutting_down(&self) -> ShuttingDown â
Returns a ShuttingDown future that resolves when shutdown has been
initiated on this Swansong.
This does not initiate shutdown â it only observes the transition from
ShutdownState::Running to ShutdownState::ShuttingDown. The future
resolves as soon as Swansong::shut_down is called (on this handle or
any parent), or when the last root handle is dropped.
The returned future does not wait for outstanding Guards to drop. To
wait for full shutdown (stopped and all guards dropped), use
Swansong::shut_down or Swansong::into_future.
ShuttingDown can also be used in blocking contexts via
ShuttingDown::block.
Sourcepub fn interrupt<T>(&self, wrapped_type: T) -> Interrupt<T> â
pub fn interrupt<T>(&self, wrapped_type: T) -> Interrupt<T> â
Wrap any type with an Interrupt, allowing it to cancel or seal on shutdown.
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.
Sourcepub fn guard(&self) -> Guard
pub fn guard(&self) -> Guard
Returns a new Guard, which forstalls shutdown until it is dropped.
The guard records the source location of this call for diagnostic
purposes; see Swansong::guard_report.
Sourcepub fn guard_count(&self) -> usize
pub fn guard_count(&self) -> usize
The total number of outstanding Guards in this Swansongâs subtree.
For a root or leaf Swansong with no children, this is just the Guards created
via this Swansong (and its clones). For a Swansong with children, it is the
sum of Guards held in this node plus all Guards in all descendant subtrees.
Child Swansong handles themselves are not counted as Guards; only real
Guard instances are.
This walks the live subtree, reading each nodeâs shards and locking each shardâs child registry. Child registries retain reusable slots, so traversal time also depends on their historical peak occupancy, even after children have dropped. Prefer not to call this in a hot path.
Sourcepub fn guard_report(&self) -> GuardReport
pub fn guard_report(&self) -> GuardReport
Report the provenance of the outstanding Guards in this Swansongâs
subtree.
Under a root created with Swansong::with_guard_report, every guard
records the source location it was created at (captured with
#[track_caller], so it points at the swansong.guard(),
swansong.guarded(..), or interrupt.guarded() call in your code;
clones inherit the location of the guard they were cloned from) and
when. This method aggregates the currently-live guards by creation site.
It is useful for debugging a shutdown that is stalled on straggling
guards â for example, by logging the report (via its
Display implementation) when
Swansong::shut_down has not completed within a deadline. Otherwise
the report only has the guard_count.
Like Swansong::guard_count, this walks the live subtree and scans retained
child-registry slots. When provenance is enabled, it also locks each shardâs guard
registry to sweep dead entries and collect live records. Registry scans take place
under their locks; this is intended for shutdown-time diagnostics rather than hot paths.
§Example
let swansong = Swansong::with_guard_report();
let guard = swansong.guard();
let report = swansong.guard_report();
assert_eq!(report.guard_count(), 1);
println!("{report}");
drop(guard);
assert!(swansong.guard_report().is_empty());Sourcepub fn child(&self) -> Swansong
pub fn child(&self) -> Swansong
Create a child Swansong linked to this parent.
The child can be independently shut down without affecting the parent. However, when
the parent is shut down, the child will also be shut down. The parentâs shutdown will
not be considered complete until the child Swansong and any associated
ShutdownCompletions are dropped.
This supports multi-level hierarchies: a child can itself have children, forming a tree. Shutdown propagates downward through the entire tree.
§Performance
Creating a child registers it in amortized O(1) time, without scanning existing children. Registration takes a parent shardâs lock and increments the parentâs shared reference count. Roots spread registrations across shards, but different threads can select the same shard; child nodes have only one shard. The lock is also shared with interrupt registration and diagnostics, so cross-thread contention is still possible. Creating a child after the parent has stopped also stops the new child.
§Example: HTTP/3 server
let server = Swansong::new();
// Each connection gets its own child swansong
let connection = server.child();
// Connection can be shut down independently (e.g., on GOAWAY)
connection.shut_down();
// Or the entire server can shut down, which also stops all connections
// server.shut_down().await;Sourcepub fn guarded<T>(&self, wrapped_type: T) -> Guarded<T> â
pub fn guarded<T>(&self, wrapped_type: T) -> Guarded<T> â
Attach a guard to the provided type, delaying shutdown until it drops.
This function returns a Guarded wrapper type provides transparent implementations of
various traits like Future and Stream, as
well as Derefing to the wrapped type. This is identical to moving a Guard 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. See Guarded for more information about trait
implementations on Guarded
Trait Implementations§
Source§impl Drop for Swansong
If we are dropping the last Swansong handle to a root node, stop the
associated futures. Dropping the last handle to a child (non-root) node
does not signal shutdown: the parent remains the governing authority, and
the child stays in its current state until the parent propagates stop or
until all Guards in the childâs subset naturally drain.
impl Drop for Swansong
If we are dropping the last Swansong handle to a root node, stop the
associated futures. Dropping the last handle to a child (non-root) node
does not signal shutdown: the parent remains the governing authority, and
the child stays in its current state until the parent propagates stop or
until all Guards in the childâs subset naturally drain.
impl Eq for Swansong
Source§impl IntoFuture for Swansong
impl IntoFuture for Swansong
Source§type IntoFuture = ShutdownCompletion
type IntoFuture = ShutdownCompletion
Source§fn into_future(self) -> <Swansong as IntoFuture>::IntoFuture
fn into_future(self) -> <Swansong as IntoFuture>::IntoFuture
Auto Trait Implementations§
impl Freeze for Swansong
impl RefUnwindSafe for Swansong
impl Send for Swansong
impl Sync for Swansong
impl Unpin for Swansong
impl UnsafeUnpin for Swansong
impl UnwindSafe for Swansong
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> CompatExt for T
impl<T> CompatExt for T
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.