feat(link): bidirectional links + trap_exit (roadmap #3)
Add Erlang-style process links so an abnormal death fate-shares across a link set, with trap_exit to convert that into a message instead. - Slot.links: Vec<Pid>, bidirectional; reset in all three lifecycle sites. - Actor.trap: Option<Sender<ExitSignal>>, fresh per spawn (a restarted child starts un-trapped; no fourth reset site). - link/unlink free functions on self_pid(); trap_exit() -> Receiver<ExitSignal> (a dedicated inbox, distinct from the monitor Down channel). - finalize_actor clears reverse links under the lock (always; keeps the cascade acyclic), then propagates abnormal deaths post-lock: trapping peer gets an ExitSignal message and survives, non-trapping peer is request_stop'd. Normal exit never propagates. Dead-pid link delivers an immediate NoProc (message if trapping, else request_stop(self) -- never a silent no-op). - ExitSignal reuses DownReason and carries no panic payload (joiner-only). Tests in tests/link.rs cover the propagate/trap/normal/dead-pid/unlink cases.
This commit is contained in:
@@ -134,4 +134,11 @@ pub struct Actor {
|
||||
/// (constructed fresh at spawn), so unlike a `Slot` field it needs no reset
|
||||
/// in the slot-recycling paths.
|
||||
pub stop: std::sync::Arc<std::sync::atomic::AtomicBool>,
|
||||
/// Trap-exit inbox (roadmap #3). `None` until the actor calls
|
||||
/// `link::trap_exit()`; `Some(tx)` means an abnormal death of a linked
|
||||
/// peer is delivered here as an `ExitSignal` *message* instead of
|
||||
/// cooperatively stopping this actor. Lives on the `Actor` (fresh per
|
||||
/// spawn) for the same reason as `stop`: no slot-recycling reset needed,
|
||||
/// and a restarted child correctly starts out *not* trapping.
|
||||
pub trap: Option<crate::channel::Sender<crate::link::ExitSignal>>,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user