Skip to content

Pipeline

Channels process incoming and outgoing data through a pipeline.

Incoming data flows through the input pipeline, where adapters can inspect, transform, or frame the data before it reaches handlers.

Outgoing data flows through the output pipeline, where adapters can build responses that are ultimately written to the transport.

Buffers are the primary mechanism used to move data through the pipeline.

Buffers

Although raw data handling in middleware can be done with byte[], it is strongly recommended to use IReadableByteBuffer, particularly for reading and framing scenarios.

Learn more about buffers.

Input Pipeline

Data delivered to the input pipeline is provided as an IReadableByteBuffer.

This buffer is a windowed view over the channel’s internal buffer:

  • It does not allocate
  • It shares the underlying memory
  • Only the unread portion (from the current offset) is exposed

Unread bytes are preserved between pipeline executions. If the pipeline does not fully consume the buffer, the remaining unread bytes will be delivered again when more data arrives.

This makes IReadableByteBuffer the preferred option for:

  • Framing protocols
  • Partial reads
  • Incremental decoding

Important

The buffer provided to the pipeline is a view, not a copy. If you need to retain data beyond the current pipeline execution, you must explicitly create a copy.

var snapshot = buffer.ToArray();

Failing to do so may result in unexpected behavior, as the underlying buffer may be compacted or reused after the pipeline completes.

Using byte[] Instead

If middleware consumes byte[] instead of IReadableByteBuffer, the internal input buffer is treated as fully consumed before the middleware even runs. This means partial reads aren’t possible with byte[], and any unprocessed data will be lost.

For this reason, unless you have a specific reason to use byte[], IReadableByteBuffer is preferred and recommended for most input scenarios.

Output Pipeline

The output pipeline is more permissive.

The following types are supported:

  • byte[]
  • IByteBuffer
  • IReadableByteBuffer
  • IWritableByteBuffer

Buffers passed through the output pipeline may be views or writable instances. At the end of the pipeline, they are written to the underlying transport.