From 5c7d3f916da9a9c93419282e943a7d45c53b9c86 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 21 Sep 2021 09:29:44 +0000 Subject: script/lei: handle SIGTSTP and SIGCONT Sometimes it's useful to pause an expensive query or refresh-mail-sync to do something else. While lei-daemon and lei/store can't be paused since they're shared across clients, per-invocation WQ workers can be paused safely using the unblockable SIGSTOP. While we're at it, drop the ETOOMANYREFS hint since it hasn't been a problem since we drastically reduced FD passing early in development. --- lib/PublicInbox/LEI.pm | 18 ++++++++++++------ script/lei | 9 ++++----- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm index f94bfa45..2df1f326 100644 --- a/lib/PublicInbox/LEI.pm +++ b/lib/PublicInbox/LEI.pm @@ -1118,23 +1118,28 @@ sub dclose { sub event_step { my ($self) = @_; local %ENV = %{$self->{env}}; - my $sock = $self->{sock}; local $current_lei = $self; eval { - while (my @fds = $recv_cmd->($sock, my $buf, 4096)) { + my $buf; + while (my @fds = $recv_cmd->($self->{sock}, $buf, 4096)) { if (scalar(@fds) == 1 && !defined($fds[0])) { return if $! == EAGAIN; next if $! == EINTR; last if $! == ECONNRESET; die "recvmsg: $!"; } - for my $fd (@fds) { - open my $rfh, '+<&=', $fd; + for (@fds) { open my $rfh, '+<&=', $_ } + } + if ($buf eq '') { + _drop_wq($self); # EOF, client disconnected + dclose($self); + } elsif ($buf =~ /\A(STOP|CONT)\z/) { + for my $wq (grep(defined, @$self{@WQ_KEYS})) { + $wq->wq_kill($buf) or $wq->wq_kill_old($buf); } + } else { die "unrecognized client signal: $buf"; } - _drop_wq($self); # EOF, client disconnected - dclose($self); }; if (my $err = $@) { eval { $self->fail($err) }; @@ -1146,6 +1151,7 @@ sub event_step_init { my ($self) = @_; my $sock = $self->{sock} or return; $self->{-event_init_done} //= do { # persist til $ops done + $sock->blocking(0); $self->SUPER::new($sock, EPOLLIN|EPOLLET); $sock; }; diff --git a/script/lei b/script/lei index 591013e3..399296ba 100755 --- a/script/lei +++ b/script/lei @@ -106,11 +106,10 @@ open my $dh, '<', '.' or die "open(.) $!"; my $buf = join("\0", scalar(@ARGV), @ARGV); while (my ($k, $v) = each %ENV) { $buf .= "\0$k=$v" } $buf .= "\0\0"; -my $n = $send_cmd->($sock, [0, 1, 2, fileno($dh)], $buf, MSG_EOR); -if (!$n) { - die "sendmsg: $! (check RLIMIT_NOFILE)\n" if $!{ETOOMANYREFS}; - die "sendmsg: $!\n"; -} +$send_cmd->($sock, [0, 1, 2, fileno($dh)], $buf, MSG_EOR) or die "sendmsg: $!"; +$SIG{TSTP} = sub { $send_cmd->($sock, [], 'STOP', MSG_EOR); kill 'STOP', $$ }; +$SIG{CONT} = sub { $send_cmd->($sock, [], 'CONT', MSG_EOR) }; + my $x_it_code = 0; while (1) { my (@fds) = $recv_cmd->($sock, my $buf, 4096 * 33); -- cgit v1.2.3-24-ge0c7