From 0f8926b742f8d9943ac718a0733725c1e89120fa Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sun, 1 Oct 2023 09:54:29 +0000 Subject: lei: deal with clients with blocked stderr lei/store can get stuck if lei-daemon is blocked, and lei-daemon can get stuck when a clients stderr is redirected to a pager that isn't consumed. So start relying on Time::HiRes::alarm to generate SIGALRM to break out of the `print' perlop. Unfortunately, this isn't easy since Perl auto-restarts all writes, so we dup(2) the destination FD and close the copy in the SIGALRM handler to force `print' to return. Most programs (MUAs, editors, etc.) aren't equipped to deal with non-blocking STDERR, so we can't make the stderr file description non-blocking. Another way to solve this problem would be to have script/lei send a non-blocking pipe to lei-daemon in the {2} slot and make script/lei splice messages from the pipe to stderr. Unfortunately, that requires more work and forces more complexity into script/lei and slow down normal cases where stderr doesn't get blocked. --- lib/PublicInbox/LEI.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/PublicInbox/LEI.pm') diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm index 1899bf38..06bc7ebd 100644 --- a/lib/PublicInbox/LEI.pm +++ b/lib/PublicInbox/LEI.pm @@ -1287,7 +1287,7 @@ sub lazy_start { undef $lk; my @st = stat($path) or die "stat($path): $!"; my $dev_ino_expect = pack('dd', $st[0], $st[1]); # dev+ino - local $oldset = PublicInbox::DS::block_signals(); + local $oldset = PublicInbox::DS::block_signals(POSIX::SIGALRM); die "incompatible narg=$narg" if $narg != 5; $PublicInbox::IPC::send_cmd or die <<""; (Socket::MsgHdr || Inline::C) missing/unconfigured (narg=$narg); @@ -1369,6 +1369,7 @@ sub lazy_start { strftime('%Y-%m-%dT%H:%M:%SZ', gmtime(time))," $$ ", @_); }; local $SIG{PIPE} = 'IGNORE'; + local $SIG{ALRM} = 'IGNORE'; open STDERR, '>&STDIN' or die "redirect stderr failed: $!"; open STDOUT, '>&STDIN' or die "redirect stdout failed: $!"; # $daemon pipe to `lei' closed, main loop begins: -- cgit v1.2.3-24-ge0c7