about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2021-08-31 11:21:25 +0000
committerEric Wong <e@80x24.org>2021-08-31 11:29:13 +0000
commitb184aaec8b65a1e50806d445878f879988403c96 (patch)
tree09f0ed302eb7c9ed5d20deaa34fce3b038a1d4f2
parent4853dee600d76ed5de5807605fa78bcd0557babd (diff)
downloadpublic-inbox-b184aaec8b65a1e50806d445878f879988403c96.tar.gz
lei: fix error reporting from lei/store -> lei-daemon
We must set autoflush to ensure timely notification of clients;
and lei-daemon must not block when waiting on reads in case of
spurious wakeups.

Finally, if no clients are connected to lei-daemon, write to
syslog to ensure the error is visible.
-rw-r--r--lib/PublicInbox/LeiStore.pm2
-rw-r--r--lib/PublicInbox/LeiStoreErr.pm14
2 files changed, 14 insertions, 2 deletions
diff --git a/lib/PublicInbox/LeiStore.pm b/lib/PublicInbox/LeiStore.pm
index 5a48c064..0652137e 100644
--- a/lib/PublicInbox/LeiStore.pm
+++ b/lib/PublicInbox/LeiStore.pm
@@ -28,6 +28,7 @@ use PublicInbox::Spawn qw(spawn);
 use List::Util qw(max);
 use File::Temp ();
 use POSIX ();
+use IO::Handle (); # ->autoflush
 
 sub new {
         my (undef, $dir, $opt) = @_;
@@ -514,6 +515,7 @@ sub write_prepare {
                 $self->ipc_lock_init("$dir/ipc.lock");
                 substr($dir, -length('/lei/store'), 10, '');
                 pipe(my ($r, $w)) or die "pipe: $!";
+                $w->autoflush(1);
                 # Mail we import into lei are private, so headers filtered out
                 # by -mda for public mail are not appropriate
                 local @PublicInbox::MDA::BAD_HEADERS = ();
diff --git a/lib/PublicInbox/LeiStoreErr.pm b/lib/PublicInbox/LeiStoreErr.pm
index 68ce96d6..5f9ba24d 100644
--- a/lib/PublicInbox/LeiStoreErr.pm
+++ b/lib/PublicInbox/LeiStoreErr.pm
@@ -8,22 +8,32 @@ use strict;
 use v5.10.1;
 use parent qw(PublicInbox::DS);
 use PublicInbox::Syscall qw(EPOLLIN EPOLLONESHOT);
+use Sys::Syslog qw(openlog syslog closelog);
+use IO::Handle (); # ->blocking
 
 sub new {
         my ($cls, $rd, $lei) = @_;
         my $self = bless { sock => $rd, store_path => $lei->store_path }, $cls;
+        $rd->blocking(0);
         $self->SUPER::new($rd, EPOLLIN | EPOLLONESHOT);
 }
 
 sub event_step {
         my ($self) = @_;
-        $self->do_read(\(my $rbuf), 4096) or return;
+        my $rbuf = $self->{rbuf} // \(my $x = '');
+        $self->do_read($rbuf, 8192, length($$rbuf)) or return;
         my $cb;
+        my $printed;
         for my $lei (values %PublicInbox::DS::DescriptorMap) {
                 $cb = $lei->can('store_path') // next;
                 next if $cb->($lei) ne $self->{store_path};
                 my $err = $lei->{2} // next;
-                print $err $rbuf;
+                print $err $$rbuf and $printed = 1;
+        }
+        if (!$printed) {
+                openlog('lei-store', 'pid,nowait,nofatal,ndelay', 'user');
+                for my $l (split(/\n/, $$rbuf)) { syslog('warning', '%s', $l) }
+                closelog(); # don't share across fork
         }
 }