* [PATCH] inboxidle: avoid needless syscalls on refresh
@ 2020-12-26 9:36 Eric Wong
2020-12-26 20:11 ` Eric Wong
0 siblings, 1 reply; 2+ messages in thread
From: Eric Wong @ 2020-12-26 9:36 UTC (permalink / raw)
To: meta
We don't have to replace a bunch of existing watches
with identical new ones. On Linux with Linux::Inotify2
installed, this avoids a storm of inotify_add_watch(2)
and inotify_rm_watch(2) syscalls on SIGHUP with -imapd
and "-extindex --watch"
---
lib/PublicInbox/InboxIdle.pm | 15 ++++++++++++---
t/imapd.t | 26 +++++---------------------
2 files changed, 17 insertions(+), 24 deletions(-)
diff --git a/lib/PublicInbox/InboxIdle.pm b/lib/PublicInbox/InboxIdle.pm
index 69da5f4f..35aed696 100644
--- a/lib/PublicInbox/InboxIdle.pm
+++ b/lib/PublicInbox/InboxIdle.pm
@@ -24,17 +24,26 @@ sub in2_arm ($$) { # PublicInbox::Config::each_inbox callback
my $dir = $ibx->{inboxdir};
my $inot = $self->{inot};
my $cur = $self->{pathmap}->{$dir} //= [];
+ my $lock = "$dir/".($ibx->version >= 2 ? 'inbox.lock' : 'ssoma.lock');
# transfer old subscriptions to the current inbox, cancel the old watch
- if (my $old_ibx = $cur->[0]) {
+ my $old_ibx = $cur->[0];
+ $cur->[0] = $ibx;
+ if ($old_ibx) {
$ibx->{unlock_subs} and
die "BUG: $dir->{unlock_subs} should not exist";
$ibx->{unlock_subs} = $old_ibx->{unlock_subs};
+
+ # Linux::Inotify2::Watch::name matches if watches are the
+ # same, no point in replacing a watch of the same name
+ if ($cur->[1]->name eq $lock) {
+ $self->{on_unlock}->{$lock} = $ibx;
+ return;
+ }
+ # rare, name changed (v1 inbox converted to v2)
$cur->[1]->cancel; # Linux::Inotify2::Watch::cancel
}
- $cur->[0] = $ibx;
- my $lock = "$dir/".($ibx->version >= 2 ? 'inbox.lock' : 'ssoma.lock');
if (my $w = $cur->[1] = $inot->watch($lock, $IN_MODIFY)) {
$self->{on_unlock}->{$w->name} = $ibx;
} else {
diff --git a/t/imapd.t b/t/imapd.t
index 43ec200c..63a86e71 100644
--- a/t/imapd.t
+++ b/t/imapd.t
@@ -296,27 +296,11 @@ $pi_cfg->each_inbox(sub {
# ensure IDLE persists across HUP, w/o extra watches or FDs
$td->kill('HUP') or BAIL_OUT "failed to kill -imapd: $!";
- SKIP: {
- skip 'no inotify fdinfo (or support)', 2 if !@ino_info;
- my (@tmp, %prev);
- local $/ = "\n";
- my $end = time + 5;
- until (time > $end) {
- select undef, undef, undef, 0.01;
- open my $fh, '<', $ino_fdinfo or
- BAIL_OUT "$ino_fdinfo: $!";
- %prev = map { $_ => 1 } @ino_info;
- @tmp = grep(/^inotify wd:/, <$fh>);
- if (scalar(@tmp) == scalar(@ino_info)) {
- delete @prev{@tmp};
- last if scalar(keys(%prev)) == @ino_info;
- }
- }
- is(scalar @tmp, scalar @ino_info,
- 'old inotify watches replaced');
- is(scalar keys %prev, scalar @ino_info,
- 'no previous watches overlap');
- };
+ for my $n (1..2) { # kick the event loop so we know HUP is done
+ my $m = $imap_client->new(%mic_opt);
+ ok($m->login && $m->IsAuthenticated && $m->logout,
+ "connection $n works after HUP");
+ }
open($fh, '<', 't/data/0001.patch') or BAIL_OUT("open: $!");
run_script(['-mda', '--no-precheck'], $env, { 0 => $fh }) or
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] inboxidle: avoid needless syscalls on refresh
2020-12-26 9:36 [PATCH] inboxidle: avoid needless syscalls on refresh Eric Wong
@ 2020-12-26 20:11 ` Eric Wong
0 siblings, 0 replies; 2+ messages in thread
From: Eric Wong @ 2020-12-26 20:11 UTC (permalink / raw)
To: meta
Eric Wong <e@80x24.org> wrote:
> We don't have to replace a bunch of existing watches
> with identical new ones. On Linux with Linux::Inotify2
> installed, this avoids a storm of inotify_add_watch(2)
> and inotify_rm_watch(2) syscalls on SIGHUP with -imapd
> and "-extindex --watch"
Addendum: this seems to fix missed wakeups after SIGHUP with
many (50K) inboxes, I'm not sure if there's some other threshold
that's missing or if there's a bug somewhere else...
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2020-12-26 20:11 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-12-26 9:36 [PATCH] inboxidle: avoid needless syscalls on refresh Eric Wong
2020-12-26 20:11 ` Eric Wong
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).