summaryrefslogtreecommitdiff
path: root/lib/Multi/Core.pm
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2014-10-21 19:45:26 +0200
committerYorhel <git@yorhel.nl>2014-10-21 19:49:08 +0200
commit60705baedb2448b6b7cfc5289678d4080b565b8e (patch)
tree675d2af8c6146021a386b957504c66c15431cc5e /lib/Multi/Core.pm
parent88ffafa464c7178d0e2e6f834bc5bad2538ce9ff (diff)
Multi: Implement clean shutdown again
That is, stop all watchers that we want to stop and only shut down when there are no active watchers anymore. This ensures that we're not shutting down in the middle of some operation.
Diffstat (limited to 'lib/Multi/Core.pm')
-rw-r--r--lib/Multi/Core.pm34
1 files changed, 28 insertions, 6 deletions
diff --git a/lib/Multi/Core.pm b/lib/Multi/Core.pm
index dfbf77c7..5bfa2a19 100644
--- a/lib/Multi/Core.pm
+++ b/lib/Multi/Core.pm
@@ -15,18 +15,26 @@ use DBI;
use POSIX 'setsid', 'pause', 'SIGUSR1';
use Exporter 'import';
-our @EXPORT = qw|pg pg_expect schedule|;
+our @EXPORT = qw|pg pg_expect schedule push_watcher|;
my $PG;
my $logger;
my $pidfile;
-my @watch;
+my $stopcv;
+my @watchers;
sub pg() { $PG }
+# Pushes a watcher to the list of watchers that need to be kept alive for as
+# long as Multi keeps running.
+sub push_watcher {
+ push @watchers, shift;
+}
+
+
sub daemon_init {
my $pid = fork();
die "fork(): $!" if !defined $pid or $pid < 0;
@@ -57,8 +65,8 @@ sub daemon_done {
tie *STDOUT, 'Multi::Core::STDIO', 'STDOUT';
tie *STDERR, 'Multi::Core::STDIO', 'STDERR';
- push @watch, AE::signal TERM => sub { unlink $pidfile };
- push @watch, AE::signal INT => sub { unlink $pidfile };
+ push_watcher AE::signal TERM => sub { $stopcv->send };
+ push_watcher AE::signal INT => sub { $stopcv->send };
}
@@ -93,11 +101,25 @@ sub load_mods {
}
+sub unload {
+ AE::log info => 'Shutting down';
+ @watchers = ();
+
+ for(keys %{$VNDB::M{modules}}) {
+ my($mod, $args) = ($_, $VNDB::M{modules}{$_});
+ next if !$args || ref($args) ne 'HASH';
+ no strict 'refs';
+ ${"Multi::$mod\::"}{unload} && "Multi::$mod"->unload();
+ }
+}
+
+
sub run {
my $p = shift;
$pidfile = "$VNDB::ROOT/data/multi.pid";
die "PID file already exists\n" if -e $pidfile;
+ $stopcv = AE::cv;
AnyEvent::Log::ctx('Multi')->attach(
AnyEvent::Log::Ctx->new(log_to_file => "$VNDB::M{log_dir}/multi.log", level => 'trace')
);
@@ -109,8 +131,8 @@ sub run {
daemon_done;
AE::log info => "Starting Multi $VNDB::S{version}";
- # Run forever
- AE::cv->recv;
+ $stopcv->recv;
+ unload;
}