Channel Write And Flush
rs-netty intentionally separates write from flush. This matters for latency, throughput, and tests.
Handler Context Writes
TCP Context<W>:
write(msg): puts the message into the current handler’s local outbox. The returnedWriteHandleis ready immediately; awaiting it is only async-style compatibility.flush(): requests a flush of messages staged by the current handler. The returned handle may be dropped or awaited.write_and_flush(msg): stages a message and creates a flush boundary.
UDP DatagramContext<W> is similar, but the target may be the current peer or an explicit peer:
write(msg)write_to(peer_addr, msg)flush()write_and_flush(msg)write_to_and_flush(peer_addr, msg)
Await Vs Fire And Forget
The handles returned by flush() and write_and_flush() may be dropped:
#![allow(unused)]
fn main() {
ctx.write_and_flush("first".to_string());
}
This requests the runtime to drain the outbox even while the handler future is still pending. tests/server_lifecycle.rs verifies that fire-and-forget flushes can send the first response before the handler returns.
If you await:
#![allow(unused)]
fn main() {
ctx.write_and_flush("first".to_string()).await?;
}
the await waits until the local socket write completes for that flush boundary. It is not a remote acknowledgement and does not mean the peer’s handler processed the data.
Plain Write Buffers
Plain write does not automatically flush. Tests cover this behavior:
tcp_context_write_buffers_until_explicit_flushudp_context_write_buffers_until_explicit_flushtcp_channel_write_buffers_until_flushudp_client_write_preserves_datagrams_until_flush
To send data:
#![allow(unused)]
fn main() {
ctx.write("sent".to_string()).await?;
ctx.flush().await?;
}
or:
#![allow(unused)]
fn main() {
ctx.write_and_flush("sent".to_string()).await?;
}
External Channel Writes
Channel<W> is the TCP external handle. It sends commands to the connection task through a bounded mpsc queue:
write(msg): waits for queue capacity, queues the message, and encodes it into the write buffer; it does not flush.flush(): waits until previously queued writes have been flushed to the socket.write_and_flush(msg): queues a message and waits until the local socket write completes.close(): requests local connection shutdown.
DatagramChannel<W> is the UDP external handle:
write_to(peer, msg): queues a datagram; it does not send.flush(): sends all pending datagrams.write_to_and_flush(peer, msg): queues and sends.close(): requests the socket task to exit.
UdpClientHandle<W> wraps write, flush, and write_and_flush for the default remote peer.
Bounded Queue Boundary
outbound_queue_size controls the channel command queue capacity. The default is 1024. When the queue is full, external write/flush/write_and_flush calls wait for capacity instead of growing without bound.
The handler-local outbox and the external channel queue are separate boundaries. Writes from Context first enter the local outbox, then the runtime drains them into the codec/write buffer or pending datagram queue.