Mojo::...Session(3pm)

🌸 Mojo::IOLoop::ReadWriteProcess::Session β€” bestie edition πŸ’…

okay so you found the page for Mojo::IOLoop::ReadWriteProcess::Session (yes that's a whole mouthful, we're calling it "the session" from here on, iykyk) 🫢


✨ NAME ✨

Mojo::IOLoop::ReadWriteProcess::Session β€” it's the session manager for handling child processes. that's the whole vibe. it wrangles your babies so you don't have to 😭


🌈 SYNOPSIS 🌈

use Mojo::IOLoop::ReadWriteProcess::Session;
use Mojo::IOLoop::ReadWriteProcess qw(process);

my $session = process()->session; # or Mojo::IOLoop::ReadWriteProcess::Session->singleton

$session->enable; # Modifies your SIG_CHLD

$session->on(collected => sub { warn "Process ".(shift->pid)." collected! "});
$session->on(collected_orphan => sub { warn "Orphan process collected! "});

$session->enable_subreaper(); # Mark the current process as subreaper
$session->disable_subreaper(); # Disable subreaper

$session->reset(); # Resets events and clear the process tables
$session->clean(); # Stop all processes that result as running and reset

πŸ’– DESCRIPTION πŸ’–

Mojo::IOLoop::ReadWriteProcess::Session is, and I cannot stress this enough, a session manager for the collected processes. it's giving babysitter for your process table. literally its whole job πŸŽ€


⭐ EVENTS ⭐

Mojo::IOLoop::ReadWriteProcess::Session inherits all events from Mojo::EventEmitter (yes, all of them, it's an heirloom piece) and can emit the following new ones. obsessed honestly.

πŸ¦‹ SIG_CHLD

$session->on(SIG_CHLD => sub {
  my ($self) = @_;
  ...
});

Emitted when we receive SIG_CHLD. that's it, that's the notification bestie πŸ’Œ

πŸ¦‹ collected

$session->on(collected => sub {
  my ($self, $process) = @_;
  ...
});

Emitted when a child process is collected and its return status is available. the lil guy came home πŸ₯Ή

πŸ¦‹ protect

$session->on(protect => sub {
  my ($self, $detail) = @_;
  my ($cb, $signal) = @$detail;
  ...
});

Emitted when protected callbacks are fired. πŸ›‘οΈ

πŸ¦‹ collected_orphan

$session->on(collected_orphan => sub {
  my ($self, $process) = @_;
  $process->pid;
  $process->exit_status;
  ...
});

Emitted when a child process is collected and its exit status is available.

⚠️ Note: here are collected processes that weren't created with Mojo::IOLoop::ReadWriteProcess. so like, strays. we take those in too 🐾

πŸ¦‹ register

$session->on(register => sub {
  my ($self, $process) = @_;
  $process->pid;
  $process->exit_status;
  ...
});

Emitted when a process is registering to a session. welcome to the group chat, new member πŸ‘‘


πŸŽ€ ATTRIBUTES πŸŽ€

Mojo::IOLoop::ReadWriteProcess::Session inherits all attributes from Mojo::EventEmitter and implements the following new ones.

πŸ’œ subreaper

use Mojo::IOLoop::ReadWriteProcess::Session qw(session);
session->enable_subreaper;
my $process = Mojo::IOLoop::ReadWriteProcess->new(code => sub { print "Hello ".$_[1] }, args => "User" );
$process->start();
$process->on( stop => sub { shift()->disable_subreaper } );
$process->stop();

# The process will print "Hello User"

Mark the current process (not the child, ok, pay attention, this matters) as subreaper on start. and it's on the invoker's behalf to disable the subreaper when the process stops, because β€” say it with me β€” it marks the current process and not the child. don't come for me, that's just how it is πŸ™ˆ

πŸ’œ collect_status

Defaults to 1. if enabled, it will automatically collect the status of the children processes. disable it in case you want to manage your process child directly and do not want to rely on automatic collect status.

πŸ‘€ If you won't overwrite your SIGCHLD handler, the SIG_CHLD event will be still emitted. so don't be shocked.

πŸ’œ handler()

use Mojo::IOLoop::ReadWriteProcess::Session qw(session);
session->handler(sub {});

Default handler for SIG_CHLD processing, used when disable() is invoked. the backup dancer πŸ’ƒ


✨ METHODS ✨

Mojo::IOLoop::ReadWriteProcess::Session inherits all methods from Mojo::EventEmitter and implements the following new ones.

🌟 enable()

use Mojo::IOLoop::ReadWriteProcess::Session qw(session);
session->enable();

Sets the SIG_CHLD handler. turn it on bestie ⚑

🌟 disable()

use Mojo::IOLoop::ReadWriteProcess::Session qw(session);
session->disable();

Disables the SIG_CHLD handler and resets with the previous one. back to how things were πŸ’«

🌟 enable_subreaper()

use Mojo::IOLoop::ReadWriteProcess qw(process);
my $p = process()->enable_subreaper;
# or
use Mojo::IOLoop::ReadWriteProcess::Session qw(session);
session->enable_subreaper;

Mark the current process (not the child!!) as subreaper. this is used typically if you want to mark further children as subreapers inside other forks. fork-ception fr fr πŸŒ€

use Mojo::IOLoop::ReadWriteProcess::Session qw(session);

my $master_p = process(
  sub {
    my $p = shift;
    $p->enable_subreaper;

    process(sub { sleep 4; exit 1 })->start();
    process(
      sub {
        sleep 4;
        process(sub { sleep 1; })->start();
      })->start();
    process(sub { sleep 4; exit 0 })->start();
    process(sub { sleep 4; die })->start();
    my $manager
      = process(sub { sleep 2 })->subreaper(1)->start();
    sleep 1 for (0 .. 10);
    $manager->stop;
    return session->all->size;
  });

$master_p->subreaper(1);
$master_p->on(collect_status => sub { $status++ });

$master_p->on(stop => sub { shift()->disable_subreaper });
$master_p->start();
session->all->size();
....

🌟 disable_subreaper()

use Mojo::IOLoop::ReadWriteProcess qw(process);
my $p = process()->disable_subreaper;

Unset the current process as subreaper. retiring from subreaper duty, iconic exit 🫑

🌟 prctl()

use Mojo::IOLoop::ReadWriteProcess qw(process);
my $p = process();
$p->prctl($option, $arg2, $arg3, $arg4, $arg5);

Internal function to execute and wrap the prctl syscall. it accepts the same arguments as prctl. yeah, exactly those ones, all of them πŸ”§

🌟 reset()

use Mojo::IOLoop::ReadWriteProcess qw(session);
session->reset;

Wipe the process tables. clean slate energy ✨

🌟 clean()

use Mojo::IOLoop::ReadWriteProcess qw(session);
session->clean;

Wipe the process tables, but before it attempts to stop running processes. so like, it asks them to leave before it clears the room 🧹

🌟 all()

use Mojo::IOLoop::ReadWriteProcess::Session qw(session);
my $collection = session->all;
$collection->size;

Returns a Mojo::Collection of Mojo::IOLoop::ReadWriteProcess that belongs to a session. the whole squad roster πŸ“‹

🌟 all_orphans()

use Mojo::IOLoop::ReadWriteProcess::Session qw(session);
my $collection = session->all_orphans;
$collection->size;

Returns a Mojo::Collection of Mojo::IOLoop::ReadWriteProcess of orphaned processes that belongs to a session. They are automatically turned into a Mojo::IOLoop::ReadWriteProcess, also if processes were created by fork(). no one gets left behind, periodt 🐣

🌟 all_processes()

use Mojo::IOLoop::ReadWriteProcess::Session qw(session);
my $collection = session->all_processes;
$collection->size;

Returns a Mojo::Collection of all Mojo::IOLoop::ReadWriteProcess known processes that belongs to a session. every single one πŸ”₯

🌟 contains()

use Mojo::IOLoop::ReadWriteProcess::Session qw(session);
my $collection = session->contains(13443);
$collection->size;

Returns true if the pid is contained in any of the process tables. vibe check on the pid βœ…

🌟 resolve()

use Mojo::IOLoop::ReadWriteProcess::Session qw(session);
my $process = session->resolve(12233);

Returns the Mojo::IOLoop::ReadWriteProcess process identified by its pid, if it belongs to the process table. found them πŸ”

🌟 orphan()

use Mojo::IOLoop::ReadWriteProcess::Session qw(session);
my $process = session->orphan(12233);

Returns the Mojo::IOLoop::ReadWriteProcess process identified by its pid, if it belongs to the process table of unknown processes. the mystery bin πŸ•΅οΈ

🌟 register()

use Mojo::IOLoop::ReadWriteProcess::Session qw(session);
my $process = session->register('pid' => Mojo::IOLoop::ReadWriteProcess->new);

Register the Mojo::IOLoop::ReadWriteProcess process to the session. signing the guestbook ✍️

🌟 unregister()

use Mojo::IOLoop::ReadWriteProcess::Session qw(session);
my $process = session->unregister(123342);

Unregister the corresponding Mojo::IOLoop::ReadWriteProcess with the given pid. leaving the group chat, no drama πŸ’”

🌟 collect()

use Mojo::IOLoop::ReadWriteProcess::Session qw(session);
my $process = session->collect(123342 => 0 => undef);

Collect the status for the given pid. scoop it up πŸ₯„

🌟 protect()

use Mojo::IOLoop::ReadWriteProcess::Session qw(session);
use POSIX;

my $return = session->protect(sub { print "Hello World\n" });

session->protect(sub { print "Hello World\n" } => SIGTERM);

Try to protect the execution of the callback from signal interrupts. shield up, bestie πŸ›‘οΈβœ¨


πŸŽ€ EXPORTS πŸŽ€

πŸ“ session()

use Mojo::IOLoop::ReadWriteProcess::Session qw(session);
session->enable_subreaper;

Returns the Mojo::IOLoop::ReadWriteProcess::Session singleton. one of them. the one. main character energy fr πŸ‘‘


🧚 DEBUGGING 🧚

You can set the MOJO_EVENTEMITTER_DEBUG environment variable to get some advanced diagnostics information printed to STDERR.

MOJO_EVENTEMITTER_DEBUG=1

Also, you can set MOJO_PROCESS_DEBUG environment variable to get diagnostics about the process execution.

MOJO_PROCESS_DEBUG=1

two lil switches and suddenly you can see everything. lowkey magical 🌟


πŸ“œ LICENSE πŸ“œ

Copyright (C) Ettore Di Giacinto.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.


πŸ‘‘ AUTHOR πŸ‘‘

Ettore Di Giacinto <edigiacinto@suse.com>


okay that's the whole page, you ate it, go run something 🫢 this was perl v5.42.0, dated 2025-07-25 β€” and it's for the manual page Mojo::...Session(3pm), in case the tab title lied to you πŸ’…βœ¨

πŸ“¦ where this page comes from