Skip to content

Spawn outgoing handler independently so sends flush immediately#281

Open
kofany wants to merge 1 commit intoaatxe:developfrom
kofany:fix/develop/spawn-outgoing-for-immediate-sends
Open

Spawn outgoing handler independently so sends flush immediately#281
kofany wants to merge 1 commit intoaatxe:developfrom
kofany:fix/develop/spawn-outgoing-for-immediate-sends

Conversation

@kofany
Copy link
Copy Markdown

@kofany kofany commented Mar 7, 2026

Summary

Fixes the surprising behavior where send_privmsg() (and all send_* methods) would buffer messages and only flush them when the incoming stream was polled. This made it impossible to use sleep() between sends to space out messages — they would all be sent at once on the next stream.next().await.

Before: Outgoing was polled inside ClientStream::poll_next(), coupling send flushing to receive polling.

After: Client::stream() spawns Outgoing as an independent tokio task via tokio::spawn(), so messages are written to the socket as soon as the runtime schedules the task.

The existing client.outgoing() API for manual control is preserved — if the user already took the outgoing future before calling stream(), there is nothing to spawn.

Changes

  • Cargo.toml: Add rt to tokio features (required for tokio::spawn, already needed in practice by all users)
  • src/client/mod.rs:
    • Client::stream(): Spawn Outgoing via tokio::spawn instead of bundling it into ClientStream
    • Remove outgoing field from ClientStream and outgoing polling from poll_next()
    • Update test helper get_client_value() from blocking thread::sleep to async tokio::time::sleep so the spawned task can flush on the current-thread test runtime

Closes #246

Test plan

  • cargo test — 67 tests + 8 doc-tests pass
  • cargo test --no-default-features — 45 tests + 7 doc-tests pass
  • cargo clippy --all-targets --all-features — no new warnings
  • git diff --check — no whitespace issues

Previously, the Outgoing future was only polled inside
ClientStream::poll_next(), which meant sent messages would not
be written to the socket until the next incoming message was
awaited. This caused surprising behavior where sleep() between
sends had no effect — all messages were batched and flushed at
once on the next stream poll.

Now, Client::stream() spawns the Outgoing handler as an
independent tokio task, so messages are flushed to the socket
as soon as the runtime can schedule the task. This makes send
timing behave as users expect.

Closes aatxe#246
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sends seem to be buffered

1 participant