X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FWatch.pm;h=082ecfb96baf5e05021fca165551d5e40cac4a87;hb=e28f33dc1b6e6a296946c0c58b43900c6cbd07f7;hp=4fbc96405cb5b799445ecc104767ebc6166b88f6;hpb=2bc961811c57bef3feef24244bf20546f3754d4f;p=public-inbox.git diff --git a/lib/PublicInbox/Watch.pm b/lib/PublicInbox/Watch.pm index 4fbc9640..082ecfb9 100644 --- a/lib/PublicInbox/Watch.pm +++ b/lib/PublicInbox/Watch.pm @@ -2,7 +2,7 @@ # License: AGPL-3.0+ # # ref: https://cr.yp.to/proto/maildir.html -# httsp://wiki2.dovecot.org/MailboxFormat/Maildir +# https://wiki2.dovecot.org/MailboxFormat/Maildir package PublicInbox::Watch; use strict; use v5.10.1; @@ -12,7 +12,6 @@ use PublicInbox::MdirReader; use PublicInbox::NetReader; use PublicInbox::Filter::Base qw(REJECT); use PublicInbox::Spamcheck; -use PublicInbox::Sigfd; use PublicInbox::DS qw(now add_timer); use PublicInbox::MID qw(mids); use PublicInbox::ContentHash qw(content_hash); @@ -53,8 +52,7 @@ sub new { # indefinitely... foreach my $pfx (qw(publicinboxwatch publicinboxlearn)) { my $k = "$pfx.watchspam"; - defined(my $dirs = $cfg->{$k}) or next; - $dirs = PublicInbox::Config::_array($dirs); + my $dirs = $cfg->get_all($k) // next; for my $dir (@$dirs) { my $uri; if (is_maildir($dir)) { @@ -284,7 +282,8 @@ sub watch_fs_init ($) { }; require PublicInbox::DirIdle; # inotify_create + EPOLL_CTL_ADD - PublicInbox::DirIdle->new([keys %{$self->{mdmap}}], $cb); + my $dir_idle = PublicInbox::DirIdle->new($cb); + $dir_idle->add_watches([keys %{$self->{mdmap}}]); } sub net_cb { # NetReader::(nntp|imap)_each callback @@ -329,8 +328,9 @@ sub imap_idle_once ($$$$) { my ($self, $mic, $intvl, $uri) = @_; my $i = $intvl //= (29 * 60); my $end = now() + $intvl; - warn "I: $uri idling for ${intvl}s\n"; + warn "# $uri idling for ${intvl}s\n"; local $0 = "IDLE $0"; + return if $self->{quit}; unless ($mic->idle) { return if $self->{quit}; return "E: IDLE failed on $uri: $!"; @@ -354,12 +354,13 @@ sub imap_idle_once ($$$$) { sub watch_imap_idle_1 ($$$) { my ($self, $uri, $intvl) = @_; my $sec = uri_section($uri); - my $mic_arg = $self->{mic_arg}->{$sec} or + my $mic_arg = $self->{net_arg}->{$sec} or die "BUG: no Mail::IMAPClient->new arg for $sec"; my $mic; local $0 = $uri->mailbox." $sec"; until ($self->{quit}) { - $mic //= PublicInbox::IMAPClient->new(%$mic_arg); + $mic //= PublicInbox::NetReader::mic_new( + $self, $mic_arg, $sec, $uri); my $err; if ($mic && $mic->IsConnected) { local $self->{mics_cached}->{$sec} = $mic; @@ -384,15 +385,13 @@ sub watch_atfork_child ($) { delete $self->{poll_pids}; delete $self->{opendirs}; PublicInbox::DS->Reset; - %SIG = (%SIG, %{$self->{sig}}, CHLD => 'DEFAULT'); + my $sig = delete $self->{sig}; + $sig->{CHLD} = 'DEFAULT'; + @SIG{keys %$sig} = values %$sig; PublicInbox::DS::sig_setmask($self->{oldset}); } -sub watch_atfork_parent ($) { - my ($self) = @_; - _done_for_now($self); - PublicInbox::DS::block_signals(); -} +sub watch_atfork_parent ($) { _done_for_now($_[0]) } sub imap_idle_requeue { # DS::add_timer callback my ($self, $uri_intvl) = @_; @@ -446,13 +445,12 @@ sub event_step { return if $self->{quit}; my $idle_todo = $self->{idle_todo}; if ($idle_todo && @$idle_todo) { - my $oldset = watch_atfork_parent($self); + watch_atfork_parent($self); eval { while (my $uri_intvl = shift(@$idle_todo)) { imap_idle_fork($self, $uri_intvl); } }; - PublicInbox::DS::sig_setmask($oldset); die $@ if $@; } fs_scan_step($self) if $self->{mdre}; @@ -489,7 +487,7 @@ sub poll_fetch_fork { # DS::add_timer callback my ($self, $intvl, $uris) = @_; return if $self->{quit}; pipe(my ($r, $w)) or die "pipe: $!"; - my $oldset = watch_atfork_parent($self); + watch_atfork_parent($self); my $seed = rand(0xffffffff); my $pid = fork; if (defined($pid) && $pid == 0) { @@ -505,7 +503,6 @@ sub poll_fetch_fork { # DS::add_timer callback close $w; _exit(0); } - PublicInbox::DS::sig_setmask($oldset); die "fork: $!" unless defined $pid; $self->{poll_pids}->{$pid} = [ $intvl, $uris ]; PublicInbox::EOFpipe->new($r, \&reap, [$pid, \&poll_fetch_reap, $self]); @@ -520,7 +517,7 @@ sub poll_fetch_reap { if ($?) { warn "W: PID=$pid died: \$?=$?\n", map { "$_\n" } @$uris; } - warn("I: will check $_ in ${intvl}s\n") for @$uris; + warn("# will check $_ in ${intvl}s\n") for @$uris; add_timer($intvl, \&poll_fetch_fork, $self, $intvl, $uris); } @@ -531,9 +528,9 @@ sub watch_imap_init ($$) { for my $uri (@{$self->{imap_order}}) { my $sec = uri_section($uri); my $mic = $mics->{$sec}; - my $intvl = $self->{imap_opt}->{$sec}->{pollInterval}; + my $intvl = $self->{cfg_opt}->{$sec}->{pollInterval}; if ($mic->has_capability('IDLE') && !$intvl) { - $intvl = $self->{imap_opt}->{$sec}->{idleInterval}; + $intvl = $self->{cfg_opt}->{$sec}->{idleInterval}; push @$idle, [ $uri, $intvl // () ]; } else { push @{$poll->{$intvl || 120}}, $uri; @@ -550,7 +547,7 @@ sub watch_nntp_init ($$) { PublicInbox::NetReader::nntp_common_init($self); for my $uri (@{$self->{nntp_order}}) { my $sec = uri_section($uri); - my $intvl = $self->{nntp_opt}->{$sec}->{pollInterval}; + my $intvl = $self->{cfg_opt}->{$sec}->{pollInterval}; push @{$poll->{$intvl || 120}}, $uri; } } @@ -568,7 +565,7 @@ sub watch { # main entry point } watch_fs_init($self) if $self->{mdre}; PublicInbox::DS->SetPostLoopCallback(sub { !$self->quit_done }); - PublicInbox::DS->EventLoop; # calls ->event_step + PublicInbox::DS::event_loop($sig, $oldset); # calls ->event_step _done_for_now($self); } @@ -683,4 +680,6 @@ EOF undef; } +sub folder_select { 'select' } # for PublicInbox::NetReader + 1;