NAME

Linux::Event::Proactor - Completion-based event loop engine for Linux::Event

SYNOPSIS

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

my $loop = Linux::Event::Loop->new(
  model   => 'proactor',
  backend => 'uring',
);

my $op = $loop->recv(
  fh          => $fh,
  len         => 4096,
  flags       => 0,
  data        => { request_id => 1 },
  on_complete => sub ($op, $result, $ctx) {
    return if $op->is_cancelled;

    if ($op->failed) {
      warn $op->error->message;
      return;
    }

    my $bytes = $result->{bytes};
    my $buf   = $result->{data};
    my $eof   = $result->{eof};
  },
);

while ($loop->live_op_count) {
  $loop->run_once;
}

DESCRIPTION

Linux::Event::Proactor is the completion-based engine in this distribution. It submits operations to a backend such as io_uring, tracks them with Linux::Event::Operation objects, and dispatches completion callbacks through a deferred callback queue.

The core invariants are:

  • callbacks never run inline

  • operations settle exactly once

  • cancellation must remain race-safe

  • the operation registry remains consistent

CONSTRUCTOR

new(%args)

Recognized arguments:

  • backend

    Backend name or backend object. Supported backend names in this release are uring and fake.

  • queue_size

    Backend queue size. Defaults to 256.

  • clock

    Clock object. The proactor uses a monotonic clock for timer operations.

  • backend-specific options

    Arguments such as submit_batch_size, cqe_entries, and sqpoll are passed through to the uring backend.

LIFECYCLE

run

Run until stop is called.

run_once

Process one round of backend completions and deferred callbacks. Returns the combined count of processed backend events and callbacks.

stop

Request that a running loop stop.

is_running

True while run is active.

OPERATIONS

Each submission method returns a Linux::Event::Operation.

read

$loop->read(fh => $fh, len => $bytes, %opt)

Result shape:

{ bytes => N, data => $string, eof => 0|1 }

write

$loop->write(fh => $fh, buf => $buffer, %opt)

Result shape:

{ bytes => N }

recv

$loop->recv(fh => $fh, len => $bytes, flags => 0, %opt)

Socket-oriented read with flags. Result shape matches read.

send

$loop->send(fh => $fh, buf => $buffer, flags => 0, %opt)

Socket-oriented write with flags. Result shape matches write.

accept

$loop->accept(fh => $listen_fh, %opt)

Result shape:

{ fh => $client_fh, addr => $sockaddr }

connect

$loop->connect(fh => $fh, addr => $sockaddr, %opt)

Successful result shape:

{}

shutdown

$loop->shutdown(fh => $fh, how => 'read' | 'write' | 'both', %opt)

Numeric shutdown constants are also accepted. Successful result shape is {}.

close

$loop->close(fh => $fh, %opt)

Successful result shape is {}.

after

$loop->after($seconds, %opt)

at

$loop->at($deadline_seconds, %opt)

Timer result shape:

{ expired => 1 }

CALLBACKS

User callbacks are supplied with on_complete. The callback ABI is:

$cb->($op, $result, $data)

The callback is never executed inline from backend completion delivery. Instead, it is queued and drained by run_once or drain_callbacks.

ACCESSORS

clock

Returns the clock object.

backend_name

Returns the backend name.

live_op_count

Returns the number of operations still registered with the loop.

drain_callbacks

Manually drain the deferred callback queue. This is primarily useful for tests and advanced control flows.

SEE ALSO

Linux::Event::Loop, Linux::Event::Operation, Linux::Event::Error, Linux::Event::Proactor::Backend, Linux::Event::Proactor::Backend::Uring, Linux::Event::Proactor::Backend::Fake