pub struct DeathNote { /* private fields */ }Expand description
The armed death note. Constructed by DeathNote::arm early in the
server run loop; its Drop writes the DISARMED line, so any ordinary
exit from the run scope — clean shutdown, error return, or a panic
unwinding through it — closes the bracket on the record.
Implementations§
Source§impl DeathNote
impl DeathNote
Sourcepub fn arm(home: &Path) -> Result<Self, ServerError>
pub fn arm(home: &Path) -> Result<Self, ServerError>
Arm the death note under the resolved Aion home: create
<home>/logs/, open the note file append-only, write the ARMED
line, install the panic hook, and start the signal watcher.
§Errors
Returns ServerError::DeathNote when a note is already armed in
this process, when the logs directory or note file cannot be created,
or when the signal watcher cannot be installed. Arming failures are
fatal to boot by design: a server that cannot record its own death is
exactly the server this module exists for.
Sourcepub fn drain_owns_termination(&self)
pub fn drain_owns_termination(&self)
Declare that the run loop’s graceful drain is now watching for a termination signal, so the watcher must only OBSERVE one.
🔴 Before this existed, the watcher observed SIGTERM/SIGINT from
the instant the note was armed — which is the instant the home is
claimed, minutes before the doors open on a large store. Registering a
handler MASKS the default action, so during the whole boot a
termination signal was caught, written down, and answered by nobody:
the drain that “owns the response” was not listening yet. The process
was un-terminable by SIGTERM for the length of its own recovery, and
then went on to serve as though nothing had been asked of it. Measured
2026-08-26: aion server stop against a booting server reported
still draining at patience against a server that was not draining,
and the server came up serving thirty seconds later.
While this is false, a termination signal ABANDONS THE BOOT. That is
the honest response: no listener is bound, no work has been accepted,
and there is nothing whatsoever to drain — so the only thing a drain
could add is delay. The exit is recorded first, and the record the
process leaves behind is reconciled as a dead incarnation by the next
boot and removed by aion server stop’s own bookkeeping.
Sourcepub fn disarm(self, reason: &str)
pub fn disarm(self, reason: &str)
Close the bracket explicitly with the run loop’s own account of how it
ended. Consumes the note; the DISARMED line is written by Drop.
Sourcepub fn record_outcome(&self, record: &OutcomeRecord)
pub fn record_outcome(&self, record: &OutcomeRecord)
Append the shutdown outcome record as an OUTCOME entry, written
BEFORE disarm so aion server stop can read the drain’s full result
after the process is gone (crate::control::outcome is the
reader). The death note already owns the “what ended this process”
seam; extending it with one entry kind keeps a single file and a
single writer — no parallel outcome channel.
A record that cannot be serialized is reported and dropped: the shutdown must not fail over its own receipt, and the reader treats the record’s absence as a state it names honestly.
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for DeathNote
impl !UnwindSafe for DeathNote
impl Freeze for DeathNote
impl Send for DeathNote
impl Sync for DeathNote
impl Unpin for DeathNote
impl UnsafeUnpin for DeathNote
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoMaybeUndefined<T> for T
impl<T> IntoMaybeUndefined<T> for T
Source§fn into_maybe_undefined(self) -> MaybeUndefined<T>
fn into_maybe_undefined(self) -> MaybeUndefined<T>
Source§impl<T> IntoOption<T> for T
impl<T> IntoOption<T> for T
Source§fn into_option(self) -> Option<T>
fn into_option(self) -> Option<T>
Source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request