Rust SDK worker refusals
Workers answer a pushed request with PushClient::reply or refuse it with
PushClient::refuse(correlation_id, code, words). PushWriter offers both
methods on the same connection. A refusal accepts the closed codes busy,
invalid, unavailable, and internal.
The wire-configured words limit is 1024 UTF-8 bytes, preserving a useful
explanation while bounding storage and decoding. Both worker APIs validate the
code and byte length before locking or writing the socket. Invalid data returns
SdkError::Protocol with the bound or fault name and no application data.
Worker identities must fit in 993 UTF-8 bytes so a malformed refusal can name
the full station within the same 1024-byte explanation bound. Registration
rejects a longer identity with worker_station_too_long; names are never
truncated.
let request = worker.recv?;
if let Frame = request
A Rust conversation caller receives
SdkError::WorkerRefused { code, words }. code is the worker code without the
worker_ prefix, and words is exact. Display returns those words; Debug
records only the code and the words' byte count. Route admission errors remain
SdkError::Conversation. Classification uses the conversation's numeric reason
code, never a prefix in its message.
The existing host-side server push awaiter returns the stable worker_<code>
alone through its legacy PushReplyRefused error. Routed calls retain the
validated refusal separately so its words reach only the authorised caller.
The wire fixture pins every code, a maximal
UTF-8 words case, complete worker and caller frames, and an unchanged opaque
reply. Its 0x0401–0x0404 conversation reasons map to worker_busy,
worker_invalid, worker_unavailable, and worker_internal. The server logs
malformed or reserved-flag replies by fault name without their bytes. A refusal
settles its slot once; duplicate replies are discarded.
Verify the SDK's live TCP pin on a socket-capable host with
cargo nextest run -p liminal-sdk --features embedded --lib refusal.