Skip to content

Commit 9c656c0

Browse files
committed
fix(runtime): avoid bounded dispatch channel stalls
1 parent 9de6238 commit 9c656c0

13 files changed

Lines changed: 36 additions & 54 deletions

File tree

engine/packages/engine/src/commands/udb/cli.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ impl SubCommand {
660660
}
661661

662662
let (tx_entries, rx_entries) =
663-
mpsc::channel::<protocol::ChangelogEntry>(10_000);
663+
mpsc::unbounded_channel::<protocol::ChangelogEntry>();
664664

665665
// Writer task: re-applies v2 entries in txn-bounded batches.
666666
// recv_many is called inside each txn iteration when the local buffer
@@ -970,7 +970,6 @@ impl SubCommand {
970970

971971
tx_entries
972972
.send(v3_entry)
973-
.await
974973
.context("writer task closed")?;
975974
}
976975
}

engine/packages/guard-core/tests/streaming_response.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,9 @@ async fn test_streaming_response_should_timeout() {
128128
drop(message_sender);
129129
}
130130

131-
async fn start_streaming_server() -> (SocketAddr, mpsc::Sender<String>) {
131+
async fn start_streaming_server() -> (SocketAddr, mpsc::UnboundedSender<String>) {
132132
// Create a channel for sending messages to the streaming endpoint
133-
let (message_tx, _message_rx) = mpsc::channel::<String>(100);
133+
let (message_tx, _message_rx) = mpsc::unbounded_channel::<String>();
134134

135135
// Bind to a random port
136136
let listener = TcpListener::bind("127.0.0.1:0")

engine/packages/pegboard-gateway/src/shared_state.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use vbare::OwnedVersionedData;
1717
use crate::{WebsocketPendingLimitReached, metrics};
1818

1919
pub struct InFlightRequestHandle {
20-
pub msg_rx: mpsc::Receiver<protocol::mk2::ToServerTunnelMessageKind>,
20+
pub msg_rx: mpsc::UnboundedReceiver<protocol::mk2::ToServerTunnelMessageKind>,
2121
/// Used to check if the request handler has been dropped.
2222
///
2323
/// This is separate from `msg_rx` there may still be messages that need to be sent to the
@@ -81,7 +81,7 @@ struct InFlightRequest {
8181
protocol_version: u16,
8282
state: InFlightRequestState,
8383
/// Sender for incoming messages to this request.
84-
msg_tx: mpsc::Sender<protocol::mk2::ToServerTunnelMessageKind>,
84+
msg_tx: mpsc::UnboundedSender<protocol::mk2::ToServerTunnelMessageKind>,
8585
/// Used to check if the request handler has been dropped.
8686
drop_tx: watch::Sender<Option<MsgGcReason>>,
8787
/// True once first message for this request has been sent (so runner learned reply_to).
@@ -184,7 +184,7 @@ impl SharedState {
184184
request_id: protocol::mk2::RequestId,
185185
state: InFlightRequestState,
186186
) -> InFlightRequestHandle {
187-
let (msg_tx, msg_rx) = mpsc::channel(128);
187+
let (msg_tx, msg_rx) = mpsc::unbounded_channel();
188188
let (drop_tx, drop_rx) = watch::channel(None);
189189

190190
let new = match self.in_flight_requests.entry_async(request_id).await {
@@ -481,7 +481,6 @@ impl SharedState {
481481
if in_flight
482482
.msg_tx
483483
.send(msg.message_kind.clone())
484-
.await
485484
.is_err()
486485
{
487486
tracing::warn!(

engine/packages/pegboard-gateway/src/tunnel_to_ws_task.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub async fn task(
2121
client_ws: WebSocketHandle,
2222
request_id: protocol::RequestId,
2323
mut stopped_sub: message::SubscriptionHandle<pegboard::workflows::actor::Stopped>,
24-
mut msg_rx: mpsc::Receiver<protocol::mk2::ToServerTunnelMessageKind>,
24+
mut msg_rx: mpsc::UnboundedReceiver<protocol::mk2::ToServerTunnelMessageKind>,
2525
mut drop_rx: watch::Receiver<Option<MsgGcReason>>,
2626
can_hibernate: bool,
2727
egress_bytes: Arc<AtomicU64>,

engine/packages/pegboard-gateway2/src/hibernation_task.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub async fn task(
2626
in_flight_req: InFlightRequestHandle,
2727
ctx: StandaloneCtx,
2828
actor_id: Id,
29-
mut msg_rx: mpsc::Receiver<protocol::ToRivetTunnelMessageKind>,
29+
mut msg_rx: mpsc::UnboundedReceiver<protocol::ToRivetTunnelMessageKind>,
3030
mut drop_rx: watch::Receiver<Option<MsgGcReason>>,
3131
egress_bytes: Arc<AtomicU64>,
3232
mut hibernation_abort_rx: watch::Receiver<()>,

engine/packages/pegboard-gateway2/src/shared_state.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ impl SharedState {
154154
request_id: protocol::RequestId,
155155
after_hibernation: bool,
156156
) -> Result<InFlightRequestCtx> {
157-
let (msg_tx, msg_rx) = mpsc::channel(128);
157+
let (msg_tx, msg_rx) = mpsc::unbounded_channel();
158158
let (drop_tx, drop_rx) = watch::channel(None);
159159

160160
let new = match self.in_flight_requests.entry_async(request_id).await {
@@ -206,7 +206,7 @@ impl SharedState {
206206
.await
207207
.context("request not in flight")?;
208208

209-
let (msg_tx, msg_rx) = mpsc::channel(128);
209+
let (msg_tx, msg_rx) = mpsc::unbounded_channel();
210210
let (drop_tx, drop_rx) = watch::channel(None);
211211

212212
req.hibernate(msg_tx, drop_tx).await;
@@ -288,7 +288,7 @@ impl Deref for SharedState {
288288
}
289289

290290
pub struct InFlightRequestCtx {
291-
pub msg_rx: mpsc::Receiver<protocol::ToRivetTunnelMessageKind>,
291+
pub msg_rx: mpsc::UnboundedReceiver<protocol::ToRivetTunnelMessageKind>,
292292
/// Used to check if the request handler has been dropped.
293293
///
294294
/// This is separate from `msg_rx` there may still be messages that need to be sent to the
@@ -676,7 +676,7 @@ impl InFlightRequest {
676676
async fn wake(
677677
&mut self,
678678
receiver_subject: String,
679-
msg_tx: mpsc::Sender<protocol::ToRivetTunnelMessageKind>,
679+
msg_tx: mpsc::UnboundedSender<protocol::ToRivetTunnelMessageKind>,
680680
drop_tx: watch::Sender<Option<MsgGcReason>>,
681681
) {
682682
self.receiver_subject = receiver_subject;
@@ -722,7 +722,7 @@ impl InFlightRequest {
722722
#[tracing::instrument(skip_all)]
723723
async fn hibernate(
724724
&mut self,
725-
msg_tx: mpsc::Sender<protocol::ToRivetTunnelMessageKind>,
725+
msg_tx: mpsc::UnboundedSender<protocol::ToRivetTunnelMessageKind>,
726726
drop_tx: watch::Sender<Option<MsgGcReason>>,
727727
) {
728728
let mut pending_tunnel_msgs = Vec::new();
@@ -816,7 +816,7 @@ impl InFlightRequest {
816816
enum InFlightRequestState {
817817
Active {
818818
/// Sender for incoming messages to this request.
819-
msg_tx: mpsc::Sender<protocol::ToRivetTunnelMessageKind>,
819+
msg_tx: mpsc::UnboundedSender<protocol::ToRivetTunnelMessageKind>,
820820
/// Used to check if the request handler has been dropped.
821821
drop_tx: watch::Sender<Option<MsgGcReason>>,
822822
last_pong: i64,
@@ -826,7 +826,7 @@ enum InFlightRequestState {
826826
PendingHibernation { hibernation_state: HibernationState },
827827
Hibernating {
828828
/// Sender for incoming messages to this request.
829-
msg_tx: mpsc::Sender<protocol::ToRivetTunnelMessageKind>,
829+
msg_tx: mpsc::UnboundedSender<protocol::ToRivetTunnelMessageKind>,
830830
/// Used to check if the hibernation handler has been dropped.
831831
drop_tx: watch::Sender<Option<MsgGcReason>>,
832832
hibernation_state: HibernationState,
@@ -853,7 +853,7 @@ pub struct PendingWebsocketMessage {
853853
#[tracing::instrument(skip_all)]
854854
async fn forward_tunnel_message(
855855
receiver_subject: &str,
856-
msg_tx: &mpsc::Sender<protocol::ToRivetTunnelMessageKind>,
856+
msg_tx: &mpsc::UnboundedSender<protocol::ToRivetTunnelMessageKind>,
857857
mut msg: protocol::ToRivetTunnelMessage,
858858
) -> Option<protocol::ToRivetTunnelMessage> {
859859
// Send message to the request handler to emulate the real network action
@@ -869,7 +869,7 @@ async fn forward_tunnel_message(
869869
"forwarding message to request handler"
870870
);
871871

872-
if let Err(send_err) = msg_tx.send(msg.message_kind).await {
872+
if let Err(send_err) = msg_tx.send(msg.message_kind) {
873873
tracing::debug!(
874874
gateway_id=%protocol::util::id_to_string(&msg.message_id.gateway_id),
875875
request_id=%protocol::util::id_to_string(&msg.message_id.request_id),

engine/packages/pegboard-gateway2/src/tunnel_to_ws_task.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub async fn task(
2121
in_flight_req: InFlightRequestHandle,
2222
client_ws: WebSocketHandle,
2323
mut stopped_sub: message::SubscriptionHandle<pegboard::workflows::actor2::Stopped>,
24-
mut msg_rx: mpsc::Receiver<protocol::ToRivetTunnelMessageKind>,
24+
mut msg_rx: mpsc::UnboundedReceiver<protocol::ToRivetTunnelMessageKind>,
2525
mut drop_rx: watch::Receiver<Option<MsgGcReason>>,
2626
can_hibernate: bool,
2727
egress_bytes: Arc<AtomicU64>,

engine/packages/universaldb/src/driver/postgres/transaction.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub struct PostgresTransactionDriver {
2424
pool: Pool,
2525
operations: TransactionOperations,
2626
committed: AtomicBool,
27-
tx_sender: OnceCell<mpsc::Sender<TransactionCommand>>,
27+
tx_sender: OnceCell<mpsc::UnboundedSender<TransactionCommand>>,
2828
}
2929

3030
impl PostgresTransactionDriver {
@@ -38,10 +38,10 @@ impl PostgresTransactionDriver {
3838
}
3939

4040
/// Get or create the transaction task
41-
async fn ensure_transaction(&self) -> Result<&mpsc::Sender<TransactionCommand>> {
41+
async fn ensure_transaction(&self) -> Result<&mpsc::UnboundedSender<TransactionCommand>> {
4242
self.tx_sender
4343
.get_or_try_init(|| async {
44-
let (sender, receiver) = mpsc::channel(100);
44+
let (sender, receiver) = mpsc::unbounded_channel();
4545

4646
// Spawn the transaction task with serializable isolation
4747
let task = TransactionTask::new(self.pool.clone(), receiver);
@@ -78,7 +78,6 @@ impl TransactionDriver for PostgresTransactionDriver {
7878
key: key.clone(),
7979
response: response_tx,
8080
})
81-
.await
8281
.context("failed to send postgres transaction command")?;
8382

8483
// Wait for response
@@ -115,7 +114,6 @@ impl TransactionDriver for PostgresTransactionDriver {
115114
offset,
116115
response: response_tx,
117116
})
118-
.await
119117
.context("failed to send postgres transaction command")?;
120118

121119
// Wait for response
@@ -166,7 +164,6 @@ impl TransactionDriver for PostgresTransactionDriver {
166164
reverse,
167165
response: response_tx,
168166
})
169-
.await
170167
.context("failed to send postgres transaction command")?;
171168

172169
// Wait for response
@@ -230,7 +227,6 @@ impl TransactionDriver for PostgresTransactionDriver {
230227
conflict_ranges,
231228
response: response_tx,
232229
})
233-
.await
234230
.context("failed to send postgres transaction command")?;
235231

236232
// Wait for commit response
@@ -288,7 +284,6 @@ impl TransactionDriver for PostgresTransactionDriver {
288284
end,
289285
response: response_tx,
290286
})
291-
.await
292287
.context("failed to send postgres command")?;
293288

294289
// Wait for response
@@ -320,7 +315,6 @@ impl TransactionDriver for PostgresTransactionDriver {
320315
conflict_ranges,
321316
response: response_tx,
322317
})
323-
.await
324318
.context("failed to send postgres transaction command")?;
325319

326320
// Wait for commit response

engine/packages/universaldb/src/driver/postgres/transaction_task.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@ pub enum TransactionCommand {
5959
/// issues while maintaining a single serializable transaction for all operations.
6060
pub struct TransactionTask {
6161
pool: Pool,
62-
receiver: mpsc::Receiver<TransactionCommand>,
62+
receiver: mpsc::UnboundedReceiver<TransactionCommand>,
6363
}
6464

6565
impl TransactionTask {
66-
pub fn new(pool: Pool, receiver: mpsc::Receiver<TransactionCommand>) -> Self {
66+
pub fn new(pool: Pool, receiver: mpsc::UnboundedReceiver<TransactionCommand>) -> Self {
6767
Self { pool, receiver }
6868
}
6969

engine/packages/universaldb/src/driver/rocksdb/transaction.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub struct RocksDbTransactionDriver {
3030
db: Arc<OptimisticTransactionDB>,
3131
operations: TransactionOperations,
3232
committed: AtomicBool,
33-
tx_sender: OnceCell<mpsc::Sender<TransactionCommand>>,
33+
tx_sender: OnceCell<mpsc::UnboundedSender<TransactionCommand>>,
3434
txn_conflict_tracker: TransactionConflictTracker,
3535
start_version: u64,
3636
}
@@ -53,10 +53,10 @@ impl RocksDbTransactionDriver {
5353
}
5454

5555
/// Get or create the transaction task for non-snapshot operations
56-
async fn ensure_transaction(&self) -> Result<&mpsc::Sender<TransactionCommand>> {
56+
async fn ensure_transaction(&self) -> Result<&mpsc::UnboundedSender<TransactionCommand>> {
5757
self.tx_sender
5858
.get_or_try_init(|| async {
59-
let (sender, receiver) = mpsc::channel(100);
59+
let (sender, receiver) = mpsc::unbounded_channel();
6060

6161
// Spawn the transaction task
6262
let task = TransactionTask::new(
@@ -97,7 +97,6 @@ impl TransactionDriver for RocksDbTransactionDriver {
9797
key: key.clone(),
9898
response: response_tx,
9999
})
100-
.await
101100
.context("failed to send rocksdb transaction command")?;
102101

103102
// Wait for response
@@ -134,7 +133,6 @@ impl TransactionDriver for RocksDbTransactionDriver {
134133
offset,
135134
response: response_tx,
136135
})
137-
.await
138136
.context("failed to send rocksdb transaction command")?;
139137

140138
// Wait for response
@@ -185,7 +183,6 @@ impl TransactionDriver for RocksDbTransactionDriver {
185183
reverse,
186184
response: response_tx,
187185
})
188-
.await
189186
.context("failed to send rocksdb transaction command")?;
190187

191188
// Wait for response
@@ -250,7 +247,6 @@ impl TransactionDriver for RocksDbTransactionDriver {
250247
conflict_ranges,
251248
response: response_tx,
252249
})
253-
.await
254250
.context("failed to send rocksdb transaction command")?;
255251

256252
// Wait for commit response
@@ -307,7 +303,6 @@ impl TransactionDriver for RocksDbTransactionDriver {
307303
end,
308304
response: response_tx,
309305
})
310-
.await
311306
.context("failed to send rocksdb command")?;
312307

313308
// Wait for response
@@ -340,7 +335,6 @@ impl TransactionDriver for RocksDbTransactionDriver {
340335
conflict_ranges,
341336
response: response_tx,
342337
})
343-
.await
344338
.context("failed to send rocksdb transaction command")?;
345339

346340
// Wait for commit response

0 commit comments

Comments
 (0)