Андрей (andy) wrote in changelog,
Андрей
andy
changelog

[ljcom] r11347: LJSUP-10483 (Selfpromo delivery mechanic...

Committer: ailyin
LJSUP-10483 (Selfpromo delivery mechanics is broken)
U   trunk/cgi-bin/LJ/Pay/Payment/PayItem.pm
Modified: trunk/cgi-bin/LJ/Pay/Payment/PayItem.pm
===================================================================
--- trunk/cgi-bin/LJ/Pay/Payment/PayItem.pm	2012-01-24 09:42:58 UTC (rev 11346)
+++ trunk/cgi-bin/LJ/Pay/Payment/PayItem.pm	2012-01-24 12:18:21 UTC (rev 11347)
@@ -612,10 +612,23 @@
 
     die "UNDEF instead of payment object" unless $payment;
 
+    my $piid = $self->get_piid;
+
+    # TODO: there's an unlikely race condition here that leads to the
+    # item being delivered twice, as long as delivery processes run
+    # simultaneously. This is only theoretical at the time of writing
+    # though because selfpromo checks that another process tries to
+    # deliver it, and all the other items are delivered from
+    # 'ljmaint.pl deliver' only, which doesn't run concurrently
+    my $reloaded = __PACKAGE__->load($piid);
+    if ( $reloaded->get_status eq 'done' ) {
+        die "item #$piid has already been delivered";
+    }
+
     ## some debug info
     ## $::VERBOSE is set in bin/ljmain.pl script, default value is 1, 2=verbose
     my $item_id = sprintf "piid=%s, item=%s, subitem=%s",
-        $self->get_piid, $self->get_item, $self->get_subitem;
+        $piid, $self->get_item, $self->get_subitem;
     warn "[$item_id]: trying to deliver" if $::VERBOSE>1;
 
     if ($self->get_giveafter > $now) {
@@ -637,7 +650,6 @@
     my ($ok, $mail_subject, $mail_message);
     eval { ($ok, $mail_subject, $mail_message) = $self->_deliver_item($payment, $buyer_u, $rcpt_u, $note_rec_change); };
     if ($@) {
-        my $piid = $self->get_piid;
         my $rid = $self->get_rcptid;
         my $bid = ($buyer_u) ? $buyer_u->{userid} : '(anonymous)';
         warn "Cannot deliver [$item_id] from $bid to $rid : $@";
@@ -648,11 +660,13 @@
     }
 
     if ($ok) {
-        my $dbh = LJ::get_db_writer()
-            or die "Could not contact global database master";
+        my $dbh = LJ::get_db_writer();
+        unless ($dbh) {
+            die "Could not contact global database master";
+        }
         my $rv = $dbh->do("UPDATE payitems SET status='done', token=?, tokenid=? ".
                     "WHERE piid=? AND status='pend'", undef, $self->get_token,
-                    $self->get_tokenid, $self->get_piid);
+                    $self->get_tokenid, $piid);
         unless ($rv) {
             warn "[$item_id]: can't set status 'done', DB error=" . $dbh->err;
         }

Tags: ailyin, andy, ljcom, pm
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments