* [PATCH] ds: reap_pids: remove redundant signal blocking
@ 2023-03-15 21:47 7% Eric Wong
0 siblings, 0 replies; 3+ results
From: Eric Wong @ 2023-03-15 21:47 UTC (permalink / raw)
To: meta
Blocking signals when reaping was done when the lei pager was
spawned by the daemon in b90e8d6e02. Shortly afterwards in
7b79c918a5, the client script took over spawning of the pager
and made b90e8d6e02 redundant.
cf. b90e8d6e02 (ds: block signals when reaping, 2021-01-10)
7b79c918a5 (lei: run pager in client script, 2021-01-10)
---
lib/PublicInbox/DS.pm | 2 --
1 file changed, 2 deletions(-)
diff --git a/lib/PublicInbox/DS.pm b/lib/PublicInbox/DS.pm
index a08e01f5..b6eaf2d7 100644
--- a/lib/PublicInbox/DS.pm
+++ b/lib/PublicInbox/DS.pm
@@ -214,7 +214,6 @@ sub await_cb ($;@) {
# that to remain the case.
sub reap_pids {
$reap_armed = undef;
- my $oldset = block_signals();
while (1) {
my $pid = waitpid(-1, WNOHANG) // last;
last if $pid <= 0;
@@ -224,7 +223,6 @@ sub reap_pids {
warn "W: reaped unknown PID=$pid: \$?=$?\n";
}
}
- sig_setmask($oldset);
}
# reentrant SIGCHLD handler (since reap_pids is not reentrant)
^ permalink raw reply related [relevance 7%]
* [PATCH 20/22] lei: run pager in client script
2021-01-10 12:14 7% [PATCH 00/22] lei query overview views Eric Wong
@ 2021-01-10 12:15 6% ` Eric Wong
0 siblings, 0 replies; 3+ results
From: Eric Wong @ 2021-01-10 12:15 UTC (permalink / raw)
To: meta
While most single keystrokes work fine when the pager is
launched from the background daemon, Ctrl-C and WINCH can cause
strangeness when connected to the wrong terminal.
---
lib/PublicInbox/LEI.pm | 26 +++++++++++++++++++-------
lib/PublicInbox/LeiQuery.pm | 5 +++--
script/lei | 28 +++++++++++++++++++++++++---
3 files changed, 47 insertions(+), 12 deletions(-)
diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm
index 1ef0cbec..d19fb311 100644
--- a/lib/PublicInbox/LEI.pm
+++ b/lib/PublicInbox/LEI.pm
@@ -26,7 +26,7 @@ use Text::Wrap qw(wrap);
use File::Path qw(mkpath);
use File::Spec;
our $quit = \&CORE::exit;
-my $recv_cmd;
+my ($recv_cmd, $send_cmd);
my $GLP = Getopt::Long::Parser->new;
$GLP->configure(qw(gnu_getopt no_ignore_case auto_abbrev));
my $GLP_PASS = Getopt::Long::Parser->new;
@@ -244,7 +244,8 @@ sub x_it ($$) { # pronounced "exit"
my $sig = ($code & 127);
$code >>= 8 unless $sig;
if (my $sock = $self->{sock}) {
- say $sock "exit=$code";
+ my $fds = [ map { fileno($_) } @$self{0..2} ];
+ $send_cmd->($sock, $fds, "exit=$code\n", 0);
} else { # for oneshot
$quit->($code);
}
@@ -635,15 +636,23 @@ sub start_pager {
chomp(my $pager = <$fh> // '');
close($fh) or warn "`git var PAGER' error: \$?=$?";
return if $pager eq 'cat' || $pager eq '';
- $env->{LESS} //= 'FRX';
- $env->{LV} //= '-c';
- $env->{COLUMNS} //= 80; # TODO TIOCGWINSZ
- $env->{MORE} //= 'FRX' if $^O eq 'freebsd';
+ # TODO TIOCGWINSZ
+ my %new_env = (LESS => 'FRX', LV => '-c', COLUMNS => 80);
+ $new_env{MORE} = 'FRX' if $^O eq 'freebsd';
pipe(my ($r, $wpager)) or return warn "pipe: $!";
my $rdr = { 0 => $r, 1 => $self->{1}, 2 => $self->{2} };
+ my $pid;
+ if (my $sock = $self->{sock}) { # lei(1) process runs it
+ delete @new_env{keys %$env}; # only set iff unset
+ my $buf = "exec 1\0".$pager;
+ while (my ($k, $v) = each %new_env) { $buf .= "\0$k=$v" };
+ my $fds = [ map { fileno($_) } @$rdr{0..2} ];
+ $send_cmd->($sock, $fds, $buf .= "\n", 0);
+ } else {
+ $pid = spawn([$pager], $env, $rdr);
+ }
$self->{1} = $wpager;
$self->{2} = $wpager if -t $self->{2};
- my $pid = spawn([$pager], $env, $rdr);
$env->{GIT_PAGER_IN_USE} = 'true'; # we may spawn git
[ $pid, @$rdr{1, 2} ];
}
@@ -731,10 +740,13 @@ sub lazy_start {
local $oldset = PublicInbox::DS::block_signals();
if ($nfd == 1) {
require PublicInbox::CmdIPC1;
+ $send_cmd = PublicInbox::CmdIPC1->can('send_cmd1');
$recv_cmd = PublicInbox::CmdIPC1->can('recv_cmd1');
} elsif ($nfd == 4) {
+ $send_cmd = PublicInbox::Spawn->can('send_cmd4');
$recv_cmd = PublicInbox::Spawn->can('recv_cmd4') // do {
require PublicInbox::CmdIPC4;
+ $send_cmd = PublicInbox::CmdIPC4->can('send_cmd4');
PublicInbox::CmdIPC4->can('recv_cmd4');
};
}
diff --git a/lib/PublicInbox/LeiQuery.pm b/lib/PublicInbox/LeiQuery.pm
index 9a383cef..6e778785 100644
--- a/lib/PublicInbox/LeiQuery.pm
+++ b/lib/PublicInbox/LeiQuery.pm
@@ -125,9 +125,10 @@ sub lei_q {
# my $wcb = PublicInbox::LeiToMail->write_cb($out, $self);
$self->{mset_opt} = \%mset_opt;
$lxs->do_query($self, \@srcs);
- if ($pid_old12) {
+ if ($pid_old12) { # [ pid, stdout, stderr ]
+ my $pid = $pid_old12->[0];
$self->{$_} = $pid_old12->[$_] for (1, 2);
- dwaitpid($pid_old12->[0], undef, $self->{sock});
+ dwaitpid($pid, undef, $self->{sock}) if $pid;
}
}
diff --git a/script/lei b/script/lei
index bea06b2c..aac8fa94 100755
--- a/script/lei
+++ b/script/lei
@@ -6,16 +6,33 @@ use v5.10.1;
use Socket qw(AF_UNIX SOCK_STREAM pack_sockaddr_un);
use PublicInbox::CmdIPC4;
my $narg = 4;
+my $recv_cmd = PublicInbox::CmdIPC4->can('recv_cmd4');
my $send_cmd = PublicInbox::CmdIPC4->can('send_cmd4') // do {
require PublicInbox::CmdIPC1; # 2nd choice
$narg = 1;
+ $recv_cmd = PublicInbox::CmdIPC1->can('recv_cmd1');
PublicInbox::CmdIPC1->can('send_cmd1');
} // do {
require PublicInbox::Spawn; # takes ~50ms even if built *sigh*
$narg = 4;
+ $recv_cmd = PublicInbox::Spawn->can('recv_cmd4');
PublicInbox::Spawn->can('send_cmd4');
};
+sub exec_cmd {
+ my ($fds, $argc, @argv) = @_;
+ my %env = map { split(/=/, $_, 2) } splice(@argv, $argc);
+ my @m = (*STDIN{IO}, '<&=', *STDOUT{IO}, '>&=',
+ *STDERR{IO}, '>&=');
+ for my $fd (@$fds) {
+ my ($old_io, $mode) = splice(@m, 0, 2);
+ open($old_io, $mode, $fd) or die "open $mode$fd: $!";
+ }
+ %ENV = (%ENV, %env);
+ exec(@argv);
+ die "exec: @argv: $!";
+}
+
my ($sock, $pwd);
if ($send_cmd && eval {
my $path = do {
@@ -68,9 +85,14 @@ Falling back to (slow) one-shot mode
select $sock;
$| = 1; # unbuffer selected $sock
$send_cmd->($sock, [ 0, 1, 2 ], $buf, 0);
- while ($buf = <$sock>) {
- $buf =~ /\Aexit=([0-9]+)\n\z/ and exit($1 + 0);
- die $buf;
+ while (my (@fds) = $recv_cmd->($sock, $buf, 4096 * 33)) {
+ if ($buf =~ /\Aexit=([0-9]+)\n\z/) {
+ exit($1);
+ } elsif ($buf =~ /\Aexec (.+)\n\z/) {
+ exec_cmd(\@fds, split(/\0/, $1));
+ } else {
+ die $buf;
+ }
}
} else { # for systems lacking Socket::MsgHdr, IO::FDPass or Inline::C
warn $@ if $@;
^ permalink raw reply related [relevance 6%]
* [PATCH 00/22] lei query overview views
@ 2021-01-10 12:14 7% Eric Wong
2021-01-10 12:15 6% ` [PATCH 20/22] lei: run pager in client script Eric Wong
0 siblings, 1 reply; 3+ results
From: Eric Wong @ 2021-01-10 12:14 UTC (permalink / raw)
To: meta
Usage summary:
lei add-external /path/to/v1-or-v2-inbox
lei add-external /path/to/another-inbox-or-ext-index
# URLs aren't supported, yet :<
lei q SEARCH TERMS GO HERE... # pager should open with JSON output
For faster startup time than what Inline::C can give:
apt-get install libsocket-msghdr-perl # Socket::Msghdr
Having neither Inline::C nor Socket::Msghdr means parallel
queries won't work.
I went back-and-forth on a bunch of things but ultimately gave
up trying to support IO::FDPass since it got too fragile and
difficult to test with the work-queue distribution.
The pager runs from the client process (if using Socket::MsgHdr
or Inline::C), now. It took at fair amount of work from my slow
brain to get pager shutdown to be instantaneous, though queries
which haven't output anything aren't easily interruptible...
The wq_* IPC stuff will be reused in the normal read-only
WWW/IMAP search at some point, too.
Eric Wong (22):
lei query + pagination sorta working
lei q: deduplicate smsg
ds: block signals when reaping
ipc: add support for asynchronous callbacks
cmd_ipc: send FDs with buffer payload
ipc: avoid excessive evals
ipc: work queue support via SOCK_SEQPACKET
ipc: eliminate ipc_worker_stop method
ipc: wq: support dynamic worker count change
ipc: drop -ipc_parent_pid field
ipc: DESTROY and wq_workers methods
lei: rename $w to $wpager for warning message
lei: fix oneshot TTY detection by passing STD*{GLOB}
lei: query: ensure pager exit is instantaneous
ipc: start supporting sending/receiving more than 3 FDs
ipc: fix IO::FDPass use with a worker limit of 1
ipc: drop unused fields, default sighandlers for wq
lei: get rid of client {pid} field
lei: fork + FD cleanup
lei: run pager in client script
lei_xsearch: transfer 4 FDs internally, drop IO::FDPass
lei: query: restore JSON output overview
MANIFEST | 4 +
lib/PublicInbox/CmdIPC4.pm | 36 ++++
lib/PublicInbox/DS.pm | 16 +-
lib/PublicInbox/Daemon.pm | 10 +-
lib/PublicInbox/ExtSearchIdx.pm | 4 +-
lib/PublicInbox/IPC.pm | 280 ++++++++++++++++++++++++++++----
lib/PublicInbox/LEI.pm | 180 +++++++++++++-------
lib/PublicInbox/LeiDedupe.pm | 29 +++-
lib/PublicInbox/LeiExternal.pm | 33 ++--
lib/PublicInbox/LeiOverview.pm | 188 +++++++++++++++++++++
lib/PublicInbox/LeiQuery.pm | 92 +++++++++++
lib/PublicInbox/LeiStore.pm | 2 +-
lib/PublicInbox/LeiToMail.pm | 2 +
lib/PublicInbox/LeiXSearch.pm | 118 +++++++++++++-
lib/PublicInbox/Search.pm | 10 +-
lib/PublicInbox/SearchView.pm | 10 +-
lib/PublicInbox/Sigfd.pm | 12 +-
lib/PublicInbox/Spawn.pm | 85 ++++++----
lib/PublicInbox/Watch.pm | 8 +-
script/lei | 76 +++++----
script/public-inbox-watch | 4 +-
t/cmd_ipc.t | 82 ++++++++++
t/ipc.t | 115 ++++++++++++-
t/lei.t | 31 +++-
t/lei_dedupe.t | 14 ++
t/lei_xsearch.t | 5 +
t/spawn.t | 33 +---
27 files changed, 1233 insertions(+), 246 deletions(-)
create mode 100644 lib/PublicInbox/CmdIPC4.pm
create mode 100644 lib/PublicInbox/LeiOverview.pm
create mode 100644 lib/PublicInbox/LeiQuery.pm
create mode 100644 t/cmd_ipc.t
^ permalink raw reply [relevance 7%]
Results 1-3 of 3 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2021-01-10 12:14 7% [PATCH 00/22] lei query overview views Eric Wong
2021-01-10 12:15 6% ` [PATCH 20/22] lei: run pager in client script Eric Wong
2023-03-15 21:47 7% [PATCH] ds: reap_pids: remove redundant signal blocking Eric Wong
Code repositories for project(s) associated with this public inbox
https://80x24.org/public-inbox.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).