]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/Daemon.pm
shrink low-bandwidth pipes under Linux
[public-inbox.git] / lib / PublicInbox / Daemon.pm
index 9125584b3b12b334a078eb1c9aec1ff4aa5f27af..6d2ae81bc1694dcc3c9fbf1ae2cbf7b249c3153d 100644 (file)
@@ -1,5 +1,5 @@
-# Copyright (C) 2015 all contributors <meta@public-inbox.org>
-# License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
+# Copyright (C) 2015-2018 all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 # contains common daemon code for the nntpd and httpd servers.
 # This may be used for read-only IMAP server if we decide to implement it.
 package PublicInbox::Daemon;
@@ -9,6 +9,7 @@ use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
 use IO::Handle;
 use IO::Socket;
 use Cwd qw/abs_path/;
+use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
 STDOUT->autoflush(1);
 STDERR->autoflush(1);
 require Danga::Socket;
@@ -102,16 +103,18 @@ sub check_absolute ($$) {
 }
 
 sub daemonize () {
-       foreach my $i (0..$#ARGV) {
-               my $arg = $ARGV[$i];
-               next unless -e $arg;
-               $ARGV[$i] = abs_path($arg);
-       }
-       check_absolute('stdout', $stdout);
-       check_absolute('stderr', $stderr);
-       check_absolute('pid-file', $pid_file);
+       if ($daemonize) {
+               foreach my $i (0..$#ARGV) {
+                       my $arg = $ARGV[$i];
+                       next unless -e $arg;
+                       $ARGV[$i] = abs_path($arg);
+               }
+               check_absolute('stdout', $stdout);
+               check_absolute('stderr', $stderr);
+               check_absolute('pid-file', $pid_file);
 
-       chdir '/' or die "chdir failed: $!";
+               chdir '/' or die "chdir failed: $!";
+       }
 
        return unless (defined $pid_file || defined $group || defined $user
                        || $daemonize);
@@ -179,10 +182,11 @@ sub worker_quit {
        Danga::Socket->SetPostLoopCallback(sub {
                my ($dmap, undef) = @_;
                my $n = 0;
+               my $now = clock_gettime(CLOCK_MONOTONIC);
 
                foreach my $s (values %$dmap) {
                        $s->can('busy') or next;
-                       if ($s->busy) {
+                       if ($s->busy($now)) {
                                ++$n;
                        } else {
                                # close as much as possible, early as possible
@@ -352,6 +356,11 @@ sub unlink_pid_file_safe_ish ($$) {
 sub master_loop {
        pipe(my ($p0, $p1)) or die "failed to create parent-pipe: $!";
        pipe(my ($r, $w)) or die "failed to create self-pipe: $!";
+
+       if ($^O eq 'linux') { # 1031: F_SETPIPE_SZ = 1031
+               fcntl($_, 1031, 4096) for ($w, $p1);
+       }
+
        IO::Handle::blocking($w, 0);
        my $set_workers = $worker_processes;
        my @caught;
@@ -456,6 +465,7 @@ sub daemon_loop ($$) {
        @listeners = map {
                PublicInbox::Listener->new($_, $post_accept)
        } @listeners;
+       PublicInbox::EvCleanup::enable();
        Danga::Socket->EventLoop;
        $parent_pipe = undef;
 }