feat(gen_server): call_timeout via recv_timeout on the reply channel
Deviates deliberately from the roadmap's monitor-based sketch (monitor + wait reply-or-Down-or-deadline + demonitor): server death is already observable on the reply channel itself - the reply sender drops as the server unwinds, closing the channel and waking the parked caller. So a bounded call is exactly recv_timeout on the reply channel, mapping Disconnected -> ServerDown and Timeout -> Timeout. No registration exists, so a timed-out call leaks nothing by construction - the guarantee the monitor design had to engineer. Semantics on timeout match Erlang: the request stays in the inbox and is still handled; the late reply's send fails harmlessly against the dropped reply receiver. CallTimeoutError keeps ServerDown and Timeout distinguishable; the infallible call() is unchanged. Tests: reply within deadline, timeout against a slow (parking) handler with elapsed bounds, server survival across an abandoned call (late reply discarded, bounded and unbounded calls keep working), and ServerDown-not-Timeout for both death paths (mid-call panic and already-gone inbox).
This commit is contained in:
+1
-1
@@ -46,7 +46,7 @@ static ALLOCATOR: preempt::PreemptingAllocator = preempt::PreemptingAllocator;
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
pub use channel::{channel, Receiver, RecvError, RecvTimeoutError, Sender};
|
||||
pub use gen_server::{CallError, CastError, GenServer, ServerRef};
|
||||
pub use gen_server::{CallError, CallTimeoutError, CastError, GenServer, ServerRef};
|
||||
pub use link::{link, trap_exit, unlink, ExitSignal};
|
||||
pub use monitor::{demonitor, monitor, Down, DownReason, Monitor, MonitorId};
|
||||
pub use mutex::{LockTimeout, Mutex, MutexGuard};
|
||||
|
||||
Reference in New Issue
Block a user