From 89d56f7988965f11e292d5f5f06163a7e75e491e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 15 Feb 2026 05:57:44 +0000 Subject: [PATCH 1/4] Initial plan From 09834e1ada3ea311c5e48ddf80675677a2fdd773 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 15 Feb 2026 06:00:45 +0000 Subject: [PATCH 2/4] Update ensure_channel doc to clarify persistence via TaskStore Co-Authored-By: Paws Co-authored-by: manthanabc <48511543+manthanabc@users.noreply.github.com> --- Cargo.lock | 2 +- crates/paws_server/src/events.rs | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3bb2272a..d35edbf7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -408,7 +408,7 @@ dependencies = [ "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper", + "hyper 1.8.1", "hyper-util", "itoa", "matchit", diff --git a/crates/paws_server/src/events.rs b/crates/paws_server/src/events.rs index f201565c..cf5e4982 100644 --- a/crates/paws_server/src/events.rs +++ b/crates/paws_server/src/events.rs @@ -130,8 +130,10 @@ impl EventBroadcaster { /// Ensures a broadcast channel exists for a task. /// - /// This is useful to create the channel before any events are broadcast, - /// so that subsequent subscribers can receive events from the buffer. + /// This creates the channel before any events are broadcast to prevent + /// events from being dropped due to a missing sender. Note that broadcast + /// channels do not buffer past events for new subscribers; event + /// persistence and replay are handled by `TaskStore`. pub async fn ensure_channel(&self, task_id: TaskId) { let mut channels = self.channels.write().await; channels From 83d3b74980aac337fb9225cc9341db9967eccbc5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 15 Feb 2026 06:26:21 +0000 Subject: [PATCH 3/4] Revert documentation change - broadcast channels DO buffer past events Co-Authored-By: Paws Co-authored-by: manthanabc <48511543+manthanabc@users.noreply.github.com> --- crates/paws_server/src/events.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/paws_server/src/events.rs b/crates/paws_server/src/events.rs index cf5e4982..f201565c 100644 --- a/crates/paws_server/src/events.rs +++ b/crates/paws_server/src/events.rs @@ -130,10 +130,8 @@ impl EventBroadcaster { /// Ensures a broadcast channel exists for a task. /// - /// This creates the channel before any events are broadcast to prevent - /// events from being dropped due to a missing sender. Note that broadcast - /// channels do not buffer past events for new subscribers; event - /// persistence and replay are handled by `TaskStore`. + /// This is useful to create the channel before any events are broadcast, + /// so that subsequent subscribers can receive events from the buffer. pub async fn ensure_channel(&self, task_id: TaskId) { let mut channels = self.channels.write().await; channels From a9ec0f8f106eb583aa039081d185f682030816bd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 15 Feb 2026 07:20:53 +0000 Subject: [PATCH 4/4] Fix ensure_channel documentation - clarify late subscriber behavior Subscribers only receive events sent AFTER subscription, not past events. Past events must be retrieved from TaskStore. Co-Authored-By: Paws Co-authored-by: manthanabc <48511543+manthanabc@users.noreply.github.com> --- crates/paws_server/src/events.rs | 38 ++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/crates/paws_server/src/events.rs b/crates/paws_server/src/events.rs index f201565c..bde27785 100644 --- a/crates/paws_server/src/events.rs +++ b/crates/paws_server/src/events.rs @@ -130,8 +130,9 @@ impl EventBroadcaster { /// Ensures a broadcast channel exists for a task. /// - /// This is useful to create the channel before any events are broadcast, - /// so that subsequent subscribers can receive events from the buffer. + /// Creates the channel before events are broadcast to prevent events from + /// being dropped when no channel exists. Note: subscribers only receive + /// events sent *after* they subscribe. For past events, use `TaskStore`. pub async fn ensure_channel(&self, task_id: TaskId) { let mut channels = self.channels.write().await; channels @@ -208,3 +209,36 @@ mod tests { // anymore. } } + +#[cfg(test)] +mod broadcast_behavior_tests { + use tokio::sync::broadcast; + + #[tokio::test] + async fn test_late_subscriber_does_not_receive_past_messages() { + // Create a broadcast channel with capacity 10 + let (tx, mut rx1) = broadcast::channel::(10); + + // Send some messages + tx.send("Message 1".to_string()).unwrap(); + tx.send("Message 2".to_string()).unwrap(); + tx.send("Message 3".to_string()).unwrap(); + + // NOW create a second subscriber AFTER messages were sent + let mut rx2 = tx.subscribe(); + + // rx1 should receive all messages (subscribed before send) + assert_eq!(rx1.recv().await.unwrap(), "Message 1"); + assert_eq!(rx1.recv().await.unwrap(), "Message 2"); + assert_eq!(rx1.recv().await.unwrap(), "Message 3"); + + // Send a new message after rx2 subscribed + tx.send("Message 4".to_string()).unwrap(); + + // rx2 should receive Message 4 (sent AFTER subscription) + // but NOT Messages 1, 2, 3 (sent BEFORE subscription) + assert_eq!(rx2.recv().await.unwrap(), "Message 4"); + + // This proves late subscribers do NOT receive past messages + } +}