IPC-Manager
view release on metacpan or search on metacpan
AI_DOCS/2026-05-13-fs-peer-cleanup-on-sigkill.md view on Meta::CPAN
When this fix is in IPC::Manager and a release lands, the harness side
will flip `Test2::Harness2::PreloadService::restartable` to return 1
(currently `0`) so a preload that exits unexpectedly is restarted
automatically. Without this fix, the next start crashes on
`<peer-id> UNIX Socket or marker file already exists`.
## Symptom
A client that registered through any `Base::FS` driver (`ConnectionUnix`,
`AtomicPipe`, `MessageFiles`) and then died ungracefully (SIGKILL,
segfault, OOM, parent-exit cascade â anything that bypasses Perl's
`DESTROY`) leaves its on-disk artifacts behind:
- `$ROUTE/{on_disk_name}` â socket file (ConnectionUnix) or directory
(AtomicPipe) for the peer
- `$ROUTE/{on_disk_name}.pid` â pidfile carrying the dead pid
- `$ROUTE/{on_disk_name}.name` â sidecar (for hashed names)
- `$ROUTE/{on_disk_name}.resume` â resume buffer (if any)
- `$ROUTE/{on_disk_name}.stats` â stats sidecar
The next process that tries to register with the same peer name croaks:
t/unit/sigkill_cleanup_ConnectionUnix.t view on Meta::CPAN
use IPC::Manager::Serializer::JSON;
my $S = 'IPC::Manager::Serializer::JSON';
my $C = 'IPC::Manager::Client::ConnectionUnix';
# Fork a child, run $code->($route) in it, then SIGKILL the child while
# whatever refs the callback returned are still in scope -- so DESTROY
# does not fire on them before SIGKILL delivers (DESTROY would call
# disconnect, which runs pre_disconnect_hook and is exactly what we want
# to skip to simulate ungraceful death). POSIX::_exit avoids the END
# / DESTROY cascade in case SIGKILL is somehow deferred.
sub kill_child_after {
my ($route, $code) = @_;
my $pid = fork;
die "fork failed: $!" unless defined $pid;
if (!$pid) {
my @keep = $code->($route);
kill 'KILL', $$;
require POSIX;
POSIX::_exit(0);
}
( run in 1.203 second using v1.01-cache-2.11-cpan-9581c071862 )