DBIx-QuickDB
view release on metacpan or search on metacpan
lib/DBIx/QuickDB/Watcher.pm view on Meta::CPAN
package DBIx::QuickDB::Watcher;
use strict;
use warnings;
our $VERSION = '0.000041';
use Carp qw/croak/;
use POSIX qw/:sys_wait_h/;
use Time::HiRes qw/sleep time/;
use Scalar::Util qw/weaken/;
use File::Path qw/remove_tree/;
use DBIx::QuickDB::Util::HashBase qw{
<db <args
<server_pid
<watcher_pid
<master_pid
<log_file
<stopped
<eliminated
<detached
<delete_data
};
sub init {
my $self = shift;
$self->{+MASTER_PID} ||= $$;
$self->{+LOG_FILE} = $self->{+DB}->gen_log;
$self->start();
weaken($self->{+DB}) if $self->{+MASTER_PID} == $$;
}
sub start {
my $self = shift;
return if $self->{+SERVER_PID};
my ($rh, $wh);
pipe($rh, $wh) or die "Could not open pipe: $!";
my $pid = fork;
die "Could not fork: $!" unless defined $pid;
if ($pid) {
close($wh);
waitpid($pid, 0);
chomp($self->{+WATCHER_PID} = <$rh>);
chomp($self->{+SERVER_PID} = <$rh>);
close($rh);
die "Did not get watcher pid!" unless $self->{+WATCHER_PID};
die "Did not get server pid!" unless $self->{+SERVER_PID};
return;
}
close($rh);
POSIX::setsid();
setpgrp(0, 0);
$pid = fork;
die "Could not fork: $!" unless defined $pid;
POSIX::_exit(0) if $pid;
$wh->autoflush(1);
print $wh "$$\n";
# In watcher now
eval { $self->watch($wh); 1 } or POSIX::_exit(1);
POSIX::_exit(0);
}
sub watch {
my $self = shift;
my ($wh) = @_;
$0 = 'db-quick-watcher';
my $kill = '';
my $hup = 0;
local $SIG{TERM} = sub { $kill = 'TERM' };
local $SIG{INT} = sub { $kill = 'INT' };
local $SIG{HUP} = sub { $hup = 1 };
my $start_pid = $$;
my $pid = $self->spawn();
print $wh "$pid\n";
close($wh);
my $mpid = $self->{+MASTER_PID};
my $spid = $self->{+SERVER_PID} or die "No server pid";
my $ddir = $self->{+DB}->dir;
my $ssig = $self->{+DB}->stop_sig // 'TERM';
( run in 2.882 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )