X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FSearchIdx.pm;h=3d80b002f709448776aada0b03033ebf38a9bad4;hb=24294059123d4edd9e31f211d72c641a5d1a0d72;hp=0b9fb4bce101b92dded63034d04b0373f8f59291;hpb=4b802d901372c284e0a3b9e515284c9e4cbfd101;p=public-inbox.git diff --git a/lib/PublicInbox/SearchIdx.pm b/lib/PublicInbox/SearchIdx.pm index 0b9fb4bc..3d80b002 100644 --- a/lib/PublicInbox/SearchIdx.pm +++ b/lib/PublicInbox/SearchIdx.pm @@ -523,6 +523,7 @@ sub link_and_save { $doc->add_boolean_term('Q' . $_) foreach @$mids; my $vivified = 0; + $self->{skel} and die "Should not have read-only skel here\n";; foreach my $mid (@$mids) { $self->each_smsg_by_mid($mid, sub { my ($cur) = @_; @@ -887,24 +888,59 @@ sub DESTROY { # remote_* subs are only used by SearchIdxPart and SearchIdxSkeleton sub remote_commit { my ($self) = @_; - print { $self->{w} } "commit\n" or die "failed to write commit: $!"; + if (my $w = $self->{w}) { + print $w "commit\n" or die "failed to write commit: $!"; + } else { + $self->commit_txn_lazy; + if (my $skel = $self->{skeleton}) { + $skel->commit_txn_lazy; + } + } } sub remote_close { my ($self) = @_; - my $pid = delete $self->{pid} or die "no process to wait on\n"; - my $w = delete $self->{w} or die "no pipe to write to\n"; - print $w "close\n" or die "failed to write to pid:$pid: $!\n"; - close $w or die "failed to close pipe for pid:$pid: $!\n"; - waitpid($pid, 0) == $pid or die "remote process did not finish"; - $? == 0 or die ref($self)." pid:$pid exited with: $?"; + if (my $w = delete $self->{w}) { + my $pid = delete $self->{pid} or die "no process to wait on\n"; + print $w "close\n" or die "failed to write to pid:$pid: $!\n"; + close $w or die "failed to close pipe for pid:$pid: $!\n"; + waitpid($pid, 0) == $pid or die "remote process did not finish"; + $? == 0 or die ref($self)." pid:$pid exited with: $?"; + } else { + die "transaction in progress $self\n" if $self->{txn}; + $self->_xdb_release if $self->{xdb}; + } } -# triggers remove_by_oid in partition or skeleton sub remote_remove { my ($self, $oid, $mid) = @_; - print { $self->{w} } "D $oid $mid\n" or - die "failed to write remove $!"; + if (my $w = $self->{w}) { + # triggers remove_by_oid in partition or skeleton + print $w "D $oid $mid\n" or die "failed to write remove $!"; + } else { + $self->begin_txn_lazy; + $self->remove_by_oid($oid, $mid); + } +} + +sub begin_txn_lazy { + my ($self) = @_; + return if $self->{txn}; + my $xdb = $self->{xdb} || $self->_xdb_acquire; + $xdb->begin_transaction; + $self->{txn} = 1; +} + +sub commit_txn_lazy { + my ($self) = @_; + delete $self->{txn} or return; + $self->{xdb}->commit_transaction; +} + +sub worker_done { + my ($self) = @_; + die "$$ $0 xdb not released\n" if $self->{xdb}; + die "$$ $0 still in transaction\n" if $self->{txn}; } 1;