diff options
Diffstat (limited to 'lib/Multi/Core.pm')
-rw-r--r-- | lib/Multi/Core.pm | 63 |
1 files changed, 53 insertions, 10 deletions
diff --git a/lib/Multi/Core.pm b/lib/Multi/Core.pm index 830ca657..6388c924 100644 --- a/lib/Multi/Core.pm +++ b/lib/Multi/Core.pm @@ -1,6 +1,6 @@ # -# Multi::Core - handles logging and the main command queue +# Multi::Core - handles spawning and logging # package Multi::Core; @@ -10,11 +10,33 @@ use warnings; use POE; use POE::Component::Pg; use DBI; +use POSIX 'setsid', 'pause', 'SIGUSR1'; sub run { my $p = shift; + die "PID file already exists\n" if -e "$VNDB::ROOT/data/multi.pid"; + + # fork + my $pid = fork(); + die "fork(): $!" if !defined $pid or $pid < 0; + + # parent process, log PID and wait for child to initialize + if($pid > 0) { + $SIG{CHLD} = sub { die "Initialization failed.\n"; }; + $SIG{ALRM} = sub { kill $pid, 9; die "Initialization timeout.\n"; }; + $SIG{USR1} = sub { + open my $P, '>', "$VNDB::ROOT/data/multi.pid" or kill($pid, 9) && die $!; + print $P $pid; + close $P; + exit; + }; + alarm(10); + pause(); + exit 1; + } + # spawn our SQL handling session my @db = @{$VNDB::O{db_login}}; my(@dsn) = DBI->parse_dsn($db[0]); @@ -29,9 +51,6 @@ sub run { ], ); - # log warnings - $SIG{__WARN__} = sub {(local$_=shift)=~s/\r?\n//;$poe_kernel->call(core=>log=>'__WARN__: '.$_)}; - $poe_kernel->run(); } @@ -53,25 +72,40 @@ sub _start { # I'm surprised the strict pagma isn't complaining about this "Multi::$mod"->spawn(%$args); } + + # finish daemonizing + kill SIGUSR1, getppid(); + setsid(); + chdir '/'; + umask 0022; + open STDIN, '/dev/null'; + tie *STDOUT, 'Multi::Core::STDIO', 'STDOUT'; + tie *STDERR, 'Multi::Core::STDIO', 'STDERR'; } -sub log { # level, msg - (my $p = eval { $_[SENDER][2]{$_[CALLER_STATE]}[0] } || '') =~ s/^Multi:://; - my $msg = sprintf '%s::%s: %s', $p, $_[CALLER_STATE], - $_[ARG1] ? sprintf($_[ARG0], @_[ARG1..$#_]) : $_[ARG0]; - +# subroutine, not supposed to be called as a POE event +sub log_msg { # msg + (my $msg = shift) =~ s/\n+$//; open(my $F, '>>', $VNDB::M{log_dir}.'/multi.log'); printf $F "[%s] %s\n", scalar localtime, $msg; close $F; } +# the POE event +sub log { # level, msg + (my $p = eval { $_[SENDER][2]{$_[CALLER_STATE]}[0] } || '') =~ s/^Multi:://; + log_msg sprintf '%s::%s: %s', $p, $_[CALLER_STATE], + $_[ARG1] ? sprintf($_[ARG0], @_[ARG1..$#_]) : $_[ARG0]; +} + + sub pg_error { # ARG: command, errmsg, [ query, params, orig_session, event-args ] my $s = $_[ARG2] ? sprintf ' (Session: %s, Query: "%s", Params: %s, Args: %s)', join(', ', $_[KERNEL]->alias_list($_[ARG4])), $_[ARG2], join(', ', $_[ARG3] ? map qq|"$_"|, @{$_[ARG3]} : '[none]'), $_[ARG5]||'' : ''; - $_[KERNEL]->call(core => log => 'SQL Error for command %s: %s %s', $_[ARG0], $_[ARG1], $s); + die sprintf 'SQL Error for command %s: %s%s', $_[ARG0], $_[ARG1], $s; } @@ -87,8 +121,17 @@ sub shutdown { $_[KERNEL]->call(core => log => 'Shutting down (%s)', $_[ARG1]); $_[KERNEL]->post(pg => 'shutdown'); $_[KERNEL]->alias_remove('core'); + unlink "$VNDB::ROOT/data/multi.pid"; } +# Tiny class for forwarding output for STDERR/STDOUT to the log file using tie(). +package Multi::Core::STDIO; + +use base 'Tie::Handle'; +sub TIEHANDLE { return bless \"$_[1]", $_[0] } +sub WRITE { Multi::Core::log_msg(${$_[0]}.': '.$_[1]) } + + 1; |