timer: send_after / cancel_timer message-delivery substrate

Add a cancellable message-delivery timer on the existing timer.rs min-heap,
the substrate the gen_server time idioms (idle/receive timeout, periodic tick,
debounce/backoff) need.

- Reason::Send { fire }: a type-erased delivery thunk. send_after (Pid<A>, via
  send_to) and send_after_named (Name<M>, via send) capture dest+msg and
  resolve the address on fire, not at arm time, so a dead target / restarted
  name is observed when it fires; a failed resolve or closed inbox is dropped
  (Erlang erlang:send_after semantics).
- Cancellation via an "armed" set keyed on the entry seq, exposed as an opaque
  TimerId. Only Send timers use it; Sleep/WaitTimeout keep their inert-stale
  behaviour untouched. pop_due fires a Send only while still armed and removes
  it, so cancel returns true iff it landed before the fire (the race signal).
  cancel is unscoped: any holder of the id can cancel (e.g. racing two servers
  and cancelling the slow path).
- peek_deadline contract documented as "<= true next deadline" so a future
  hierarchical timing wheel can back Timers without touching send_after or the
  scheduler idle path. call_timeout left on recv_timeout (blast radius).

Tests: Timers-level (fire/cancel/race/clear/ordering) plus scheduler-level
delivery for both Name<M> and Pid<A>, cancel-prevents-delivery, and silent
drop on unresolved name / dead pid. Green on rq-mutex/rq-mpmc/rq-striped.
This commit is contained in:
smarm-agent
2026-06-18 14:28:54 +00:00
parent 5cb7f6a491
commit 61520bf2cc
6 changed files with 356 additions and 21 deletions
+4 -3
View File
@@ -65,11 +65,12 @@ pub use registry::{
};
pub use runtime::{init, Config, Runtime};
pub use scheduler::{
block_on_io, request_stop, run, self_pid, sleep, spawn, spawn_addr, spawn_under, wait_readable,
wait_readable_timeout, wait_writable, wait_writable_timeout, yield_now, FdArm, JoinError,
JoinHandle,
block_on_io, cancel_timer, request_stop, run, self_pid, send_after, send_after_named, sleep,
spawn, spawn_addr, spawn_under, wait_readable, wait_readable_timeout, wait_writable,
wait_writable_timeout, yield_now, FdArm, JoinError, JoinHandle,
};
pub use supervisor::{ChildSpec, OneForOne, Restart, Signal, Strategy};
pub use timer::TimerId;
// ---------------------------------------------------------------------------
// check!()