X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FWatch.pm;h=2698c44ab34b8cebaec2e321f75a560b53b1afe2;hb=03c9119ec613fa43dcf0a50b5f35754f13228bc8;hp=5f78613961db1058506b8193c4ea7bd55c0522f3;hpb=cee907599bb7eda0695ae91cf8d633670a88d6c7;p=public-inbox.git diff --git a/lib/PublicInbox/Watch.pm b/lib/PublicInbox/Watch.pm index 5f786139..2698c44a 100644 --- a/lib/PublicInbox/Watch.pm +++ b/lib/PublicInbox/Watch.pm @@ -134,15 +134,34 @@ sub _done_for_now { sub remove_eml_i { # each_inbox callback my ($ibx, $arg) = @_; my ($self, $eml, $loc) = @$arg; + eval { - my $im = _importer_for($self, $ibx); - $im->remove($eml, 'spam'); - if (my $scrub = $ibx->filter($im)) { - my $scrubbed = $scrub->scrub($eml, 1); - if ($scrubbed && $scrubbed != REJECT) { - $im->remove($scrubbed, 'spam'); + # try to avoid taking a lock or unnecessary spawning + my $im = $self->{importers}->{"$ibx"}; + my $scrubbed; + if ((!$im || !$im->active) && $ibx->over) { + if (content_exists($ibx, $eml)) { + # continue + } elsif (my $scrub = $ibx->filter($im)) { + $scrubbed = $scrub->scrub($eml, 1); + if ($scrubbed && $scrubbed != REJECT && + !content_exists($ibx, $scrubbed)) { + return; + } + } else { + return; } } + + $im //= _importer_for($self, $ibx); # may spawn fast-import + $im->remove($eml, 'spam'); + $scrubbed //= do { + my $scrub = $ibx->filter($im); + $scrub ? $scrub->scrub($eml, 1) : undef; + }; + if ($scrubbed && $scrubbed != REJECT) { + $im->remove($scrubbed, 'spam'); + } }; if ($@) { warn "error removing spam at: $loc from $ibx->{name}: $@\n"; @@ -570,6 +589,7 @@ sub watch_atfork_child ($) { sub watch_atfork_parent ($) { my ($self) = @_; _done_for_now($self); + PublicInbox::Sigfd::block_signals(); } sub imap_idle_requeue ($) { # DS::add_timer callback @@ -609,10 +629,14 @@ sub event_step { return if $self->{quit}; my $idle_todo = $self->{idle_todo}; if ($idle_todo && @$idle_todo) { - watch_atfork_parent($self); - while (my $url_intvl = shift(@$idle_todo)) { - imap_idle_fork($self, $url_intvl); - } + my $oldset = watch_atfork_parent($self); + eval { + while (my $url_intvl = shift(@$idle_todo)) { + imap_idle_fork($self, $url_intvl); + } + }; + PublicInbox::Sigfd::sig_setmask($oldset); + die $@ if $@; } goto(&fs_scan_step) if $self->{mdre}; } @@ -665,9 +689,9 @@ sub watch_nntp_fetch_all ($$) { sub poll_fetch_fork ($) { # DS::add_timer callback my ($self, $intvl, $urls) = @{$_[0]}; return if $self->{quit}; - watch_atfork_parent($self); - defined(my $pid = fork) or die "fork: $!"; - if ($pid == 0) { + my $oldset = watch_atfork_parent($self); + my $pid = fork; + if (defined($pid) && $pid == 0) { watch_atfork_child($self); if ($urls->[0] =~ m!\Aimaps?://!i) { watch_imap_fetch_all($self, $urls); @@ -676,6 +700,8 @@ sub poll_fetch_fork ($) { # DS::add_timer callback } _exit(0); } + PublicInbox::Sigfd::sig_setmask($oldset); + die "fork: $!" unless defined $pid; $self->{poll_pids}->{$pid} = [ $intvl, $urls ]; PublicInbox::DS::dwaitpid($pid, \&poll_fetch_reap, $self); }