You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite. Learn more
Overall assessment: The fix is mechanically correct and well-scoped. Converting bounded channels to unbounded removes the deadlock risk where a slow consumer causes back-pressure that blocks a sender holding a shared resource. One real issue was introduced, and a few areas deserve attention before merge.
Issue 1 — Spurious async fn on forward_tunnel_message (introduced by this PR)
In the base branch, forward_tunnel_message was async because it called msg_tx.send(...).await. After this PR removes .await (the send is now synchronous), the async fn annotation was left in place but the body no longer contains any await point. The function generates an unnecessary Future wrapper on every call and is misleading to future readers.
// Current (PR) — misleading:asyncfn forward_tunnel_message(...) -> Option<...> {// ... no .await anywhere in the bodyifletErr(send_err) = msg_tx.send(msg.message_kind){ ...}}// Should be:fn forward_tunnel_message(...) -> Option<...> { ...}
The call sites that still use .await on this function will also need their .await suffixes removed.
The transaction task channels (formerly capped at 100) now accept an unbounded number of commands. Each TransactionCommand variant carries heap-allocated Vec<u8> key/value data plus oneshot::Sender response channels. If the transaction task falls behind (e.g. under DB contention, serializable conflict retries), senders can flood the channel with unbounded pending commands.
The CLAUDE.md design constraint for actor-owned dispatch inboxes explicitly states: "Do not await bounded mpsc::Sender::send. Use try_reserve helpers and return actor.overloaded." While these are DB transaction bridges rather than actor dispatch, the underlying concern is identical. A bounded channel with try_send and an explicit transaction.busy error would give callers actionable feedback and bound memory. Alternatively, if transactions are always short-lived and the caller count is bounded, that assumption should be documented inline.
The receiver is bound to _message_rx which is dropped immediately (the _ prefix causes immediate drop). Any message_tx.send(...) will immediately return Err because the receiver is gone. This is pre-existing behavior and works for the current test pattern, but is fragile. Consider naming it _no_receiver or adding a comment explaining the pattern.
Positive observations
The fix correctly identifies that bounded_sender.send(...).await in a shared-state dispatch loop is the root cause of the stall. Conversion to unbounded is the right approach for channels where the receiver is a short-lived handler task.
Removing .await on UnboundedSender::send is correct — the call is now synchronous.
The UDB migration CLI channel (tx_entries/rx_entries) is a good fit for unbounded: the reader uses recv_many with transaction-bounded batches and the writer is a sole consumer in a dedicated tokio::spawn.
Tunnel forwarding channels in pegboard-gateway1 and pegboard-gateway2 are reasonable candidates for unbounded because the receiver is a per-request task with a bounded lifetime and the sender no longer holds locks across the send.
Convention check
No rivet.gg references introduced.
No _ => fall-through enum match arms introduced.
No println!/eprintln! introduced in non-test Rust code.
No std::sync::Mutex or Mutex<HashMap> introduced.
Tracing fields use structured form correctly in existing log calls.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Please include a summary of the changes and the related issue. Please also include relevant motivation and context.
Type of change
How Has This Been Tested?
Please describe the tests that you ran to verify your changes.
Checklist: