NAME
Linux::Event::Fork - Child process management integrated with Linux::Event
SYNOPSIS
use v5.36;
use Linux::Event;
use Linux::Event::Fork;
my $loop = Linux::Event->new;
my $forker = Linux::Event::Fork->new($loop,
max_children => 4, # 0 = unlimited
);
my $h = $forker->spawn(
cmd => [ $^X, '-we', 'print "hello\n"; exit 0' ],
on_stdout => sub ($child, $chunk) {
print $chunk;
},
on_exit => sub ($child, $exit) {
printf "pid=%d exited=%d code=%d\n",
$exit->pid, $exit->exited, ($exit->exited ? $exit->code : -1);
$loop->stop;
},
);
if ($h->isa('Linux::Event::Fork::Request')) {
warn "queued\n";
}
$loop->run;
DESCRIPTION
Linux::Event::Fork runs child processes while integrating their lifecycle and I/O streams (stdout/stderr/stdin) with a Linux::Event loop.
Features:
Nonblocking stdout/stderr capture (chunk callbacks)
Optional streaming stdin (parent -> child)
Timeout support with optional escalation to SIGKILL
Bounded parallelism (max_children) with queueing
Drain callback when all work completes
Cancel queued requests (bulk or per-request)
Introspection (running/queued/max_children)
EXECUTION MODEL
All on_* callbacks run in the parent process, inside the event loop.
Only the child => sub { ... } callback runs in the child process.
Stream directions:
stdin : parent -> child
stdout : child -> parent
stderr : child -> parent
There is no "on_stdin" callback. Stdin is a write stream to the child.
CONSTRUCTOR
new($loop, %args)
my $forker = Linux::Event::Fork->new($loop,
max_children => 4, # optional (default 0 = unlimited)
);
Constructs a forker bound to a specific event loop.
Arguments:
METHODS
loop
my $loop = $forker->loop;
Returns the underlying Linux::Event loop.
spawn(%spec)
my $h = $forker->spawn(%spec);
Starts a child immediately if capacity allows, otherwise enqueues the request.
Returns either:
-
If started immediately.
-
If queued due to
max_children.
spawn options
Exactly one of:
- cmd => \@argv
-
Execs the given argv in the child.
- child => sub { ... }
-
Runs the coderef in the child process. If it returns, the child exits with 127.
Optional:
- on_start => sub ($child) { ... }
-
Called in the parent after the child handle is created (and before the loop has necessarily observed any I/O).
- on_stdout => sub ($child, $chunk) { ... }
-
Called in the parent when the child writes to stdout.
- on_stderr => sub ($child, $chunk) { ... }
-
Called in the parent when the child writes to stderr.
- on_exit => sub ($child, $exit) { ... }
-
Called in the parent after the child has fully exited.
$exitis a Linux::Event::Fork::Exit. - capture_stdout => $bool
-
Force stdout capture on/off. Default: true if
on_stdoutis provided, otherwise false. - capture_stderr => $bool
-
Force stderr capture on/off. Default: true if
on_stderris provided, otherwise false. - stdin => $string
-
If provided, writes this string to the child's stdin after start.
- stdin_pipe => $bool
-
If true, keeps stdin open for streaming writes using the child handle. If false (default), stdin is closed after the initial
stdinwrite (if any). - timeout => $seconds
-
Soft timeout. When it fires: calls
on_timeout(if any) and sends SIGTERM. - on_timeout => sub ($child) { ... }
-
Called in the parent when
timeoutfires. - timeout_kill => $seconds
-
If set, after SIGTERM waits this many seconds and then sends SIGKILL if still alive.
- cwd => $dir
-
Changes working directory in the child before exec/callback.
- umask => $mask
-
Sets umask in the child before exec/callback.
- clear_env => $bool
-
If true, clears %ENV in the child before applying
env. - env => \%env
-
Merges these variables into %ENV in the child before exec/callback.
- tag => $string
-
Opaque tag stored on the child/request handles.
- data => $scalar
-
Opaque user data stored on the child/request handles.
max_children([$n])
my $n = $forker->max_children;
$forker->max_children(8);
Get or set the concurrency limit.
0 means unlimited.
Increasing the limit may immediately start queued requests. Decreasing the limit does not affect running children; it only limits future starts.
running
my $n = $forker->running;
Number of children currently running (tracked for capacity control).
queued
my $n = $forker->queued;
Number of queued requests waiting for capacity.
drain(on_done => sub ($forker) { ... })
$forker->drain(on_done => sub ($forker) {
...
});
Registers a callback that fires once when:
running == 0
AND
queue is empty
If already drained at registration time, the callback fires immediately on the next opportunity inside the loop.
cancel_queued([$predicate])
my $n = $forker->cancel_queued;
my $n = $forker->cancel_queued(sub ($req) { ... });
Cancels queued requests. If a predicate is provided, only queued requests for which the predicate returns true are canceled.
Returns the number canceled.
RETURN OBJECTS
Linux::Event::Fork::Child
Represents a running (or exited) child process.
See Linux::Event::Fork::Child.
Linux::Event::Fork::Request
Represents a queued spawn request that has not yet started.
See Linux::Event::Fork::Request.
CAPACITY AND QUEUE MODEL
When max_children is non-zero:
running < max_children -> spawn immediately (Child)
running >= max_children -> enqueue (Request)
When a child exits, capacity is released and queued requests start FIFO.
Changing max_children at runtime affects future starts, and increasing the limit may immediately start queued requests.
WHAT THIS MODULE IS NOT
This is not a supervisor, scheduler, or promise framework.
It is a deterministic process management layer for child processes built directly on Linux::Event.
AUTHOR
Joshua S. Day
LICENSE
Same terms as Perl itself.