This should further mitigate lock contention problems
when -watch is configured to watch on a Maildir for spam
while performing a large NNTP import.
There is now a small risk a message won't get removed because if
it's in the current (uncommitted) fast-import batch, but
unlikely given the batch size is now only 10 messages.
If a that small window is hit, flipping the \Seen flag
(e.g. marking it unread, and then read again) will trigger
another removal attempt via IMAP or Maildir.
+# true if locked and active
+sub active { !!$_[0]->{out} }
+
sub done {
my ($self) = @_;
my $w = delete $self->{out} or return;
sub done {
my ($self) = @_;
my $w = delete $self->{out} or return;
# public
sub barrier { checkpoint($_[0], 1) };
# public
sub barrier { checkpoint($_[0], 1) };
+# true if locked and active
+sub active { !!$_[0]->{im} }
+
# public
sub done {
my ($self) = @_;
# public
sub done {
my ($self) = @_;
sub remove_eml_i { # each_inbox callback
my ($ibx, $arg) = @_;
my ($self, $eml, $loc) = @$arg;
sub remove_eml_i { # each_inbox callback
my ($ibx, $arg) = @_;
my ($self, $eml, $loc) = @$arg;
- 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";
};
if ($@) {
warn "error removing spam at: $loc from $ibx->{name}: $@\n";