NAME

Linux::Event::Stream - Buffered, backpressure-aware I/O for nonblocking file descriptors

SYNOPSIS

use v5.36;
use Linux::Event;
use Linux::Event::Stream;

my $loop = Linux::Event->new;

my $stream = Linux::Event::Stream->new(
  loop => $loop,
  fh   => $fh,

  on_read  => sub ($stream, $bytes, $data) {
    # Called whenever bytes are received.
    # If you call $stream->close or $stream->close_after_drain here,
    # further callbacks will not be invoked.
  },

  on_error => sub ($stream, $errno, $data) {
    # Called on fatal I/O error. Stream will close immediately after this.
  },

  on_close => sub ($stream, $data) {
    # Called exactly once when the stream closes.
  },

  high_watermark => 1_048_576,  # bytes
  low_watermark  =>   262_144,  # bytes

  read_size         => 8192,
  max_read_per_tick => 0,

  data => $user_data,
);

$stream->write("hello\n");
$loop->run;

DESCRIPTION

Linux::Event::Stream provides buffered, backpressure-aware I/O on top of Linux::Event watchers.

It wraps a nonblocking file descriptor and adds:

  • Write buffering

  • High/low watermark backpressure tracking (hysteresis latch)

  • Graceful close-after-drain support

  • Optional read throttling

Stream does not create sockets, perform protocol parsing, or modify the event loop. It is a small policy layer over a file descriptor.

CONSTRUCTOR

new(%args)

Required arguments:

loop

A Linux::Event loop instance.

fh

A filehandle or socket. It will be placed into nonblocking mode.

Optional arguments:

on_read => sub ($stream, $bytes, $data)

Called whenever bytes are read.

This callback may call close or close_after_drain.

on_error => sub ($stream, $errno, $data)

Called when a fatal I/O error occurs.

After firing on_error, the stream closes immediately (buffer is discarded) and then on_close fires.

on_close => sub ($stream, $data)

Called exactly once when the stream closes (for any reason).

high_watermark

Defaults to 1MB.

If pending buffered bytes exceed this value, is_write_blocked becomes true.

low_watermark

Defaults to 256KB.

When pending buffered bytes drop below this value, is_write_blocked becomes false.

If low_watermark is greater than high_watermark, it is clamped to high_watermark.

read_size

Maximum bytes per sysread() call (default 8192).

max_read_per_tick

Limit total bytes read per loop tick. 0 means unlimited.

data

Opaque user data passed to callbacks.

close_fh

If true, the underlying filehandle is closed when the stream closes.

By default Stream does not assume ownership of the filehandle.

METHODS

write($bytes)

Queues bytes for sending and returns true if the bytes were accepted for buffering.

If there is no pending buffered data, Stream attempts an immediate syswrite() before buffering the remainder.

A true return value does not imply that the peer has received the bytes; delivery is asynchronous.

buffered_bytes

Returns the number of bytes currently buffered and not yet written to the file descriptor.

is_write_blocked

Returns true if Stream is in a backpressured state due to the configured watermarks.

This is a hysteresis latch: it becomes true above high_watermark and becomes false below low_watermark.

pause_read

Disables read notifications.

resume_read

Re-enables read notifications (unless the stream is closing).

close

Immediately closes the stream.

Buffered data is discarded.

close_after_drain

Stops reading and closes once all buffered data has been written.

is_closed

Returns true once closed.

is_closing

Returns true if close_after_drain has been requested.

BACKPRESSURE SEMANTICS

Watermarks operate on pending buffered bytes (buffered_bytes).

is_write_blocked transitions:

  • false → true when buffered_bytes > high_watermark

  • true → false when buffered_bytes < low_watermark

The transition back to false occurs inside the WRITE-ready drain path, not necessarily during a READ event on the peer.

INTEGRATION NOTES

Stream is intended to be composed by higher-level modules (for example a future Linux::Event::Listen connection wrapper) to provide consistent buffered I/O and backpressure behavior.

AUTHOR

Joshua S. Day

LICENSE

Same terms as Perl itself.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 543:

Non-ASCII character seen before =encoding in '→'. Assuming UTF-8