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

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

Committer: ailyin
LJSUP-10483 (Selfpromo delivery mechanics is broken)
U   trunk/cgi-bin/LJ/Pay/Payment/PayItem/SelfPromo.pm
U   trunk/cgi-bin/LJ/Pay/SelfPromo.pm
Modified: trunk/cgi-bin/LJ/Pay/Payment/PayItem/SelfPromo.pm
===================================================================
--- trunk/cgi-bin/LJ/Pay/Payment/PayItem/SelfPromo.pm	2012-01-23 12:05:56 UTC (rev 11340)
+++ trunk/cgi-bin/LJ/Pay/Payment/PayItem/SelfPromo.pm	2012-01-23 15:03:53 UTC (rev 11341)
@@ -70,10 +70,17 @@
 sub _deliver_item {
     my ( $self, $payment, $buyer_u, $rcpt_u, $note_rec_change ) = @_;
 
+    LJ::Pay::SelfPromo->debug_msg("delivery of a selfpromo item requested");
+    LJ::Pay::SelfPromo->debug_msg( "piid=" . $self->get_piid );
+
     # if we cannot get a lock straight away, let this be delivered later;
     # resolves race condition with ljmaint.pl and webs trying to deliver
     # the same item simultaneously
-    return if LJ::Pay::SelfPromo->lock_taken_elsewhere;
+    if ( LJ::Pay::SelfPromo->lock_taken_elsewhere ) {
+        LJ::Pay::SelfPromo->debug_msg(
+            "actually, another process got the lock, quitting");
+        return;
+    }
 
     # this should be temporary until we l10n the shop
     my $lang = ($rcpt_u && $rcpt_u->prop('browselang')) ? $rcpt_u->prop('browselang') : $LJ::DEFAULT_LANG;
@@ -82,11 +89,16 @@
         return LJ::Lang::get_text( $lang, $code, undef, $params );
     };
 
+    LJ::Pay::SelfPromo->debug_msg("acquiring the lock");
     my $lock = LJ::Pay::SelfPromo->lock;
+    LJ::Pay::SelfPromo->debug_msg("got the lock");
 
+    LJ::Pay::SelfPromo->debug_msg("checking the current entry");
     LJ::Pay::SelfPromo->check_current_entry;
+    LJ::Pay::SelfPromo->debug_msg("current entry checked");
 
     my $type = $self->get_prop('selfpromo_type');
+    LJ::Pay::SelfPromo->debug_msg("item type: $type");
 
     # if there's an entry being promoted, deactivate it, and
     # then handle any refund if need be
@@ -95,6 +107,9 @@
     # also only cancel the current promotion
     my $entry_promoted;
     if ( $entry_promoted = LJ::Pay::SelfPromo->current_entry ) {
+        LJ::Pay::SelfPromo->debug_msg(
+            "cancelling the current entry" . $entry_promoted->url );
+
         LJ::Pay::SelfPromo->deactivate_entry(
             'entry'   => $entry_promoted,
             'reason'  => 'buyout',
@@ -102,13 +117,22 @@
         );
 
         if ( my $refund_userid = $self->get_prop('selfpromo_refund_userid') ) {
+            LJ::Pay::SelfPromo->debug_msg(
+                "issuing a refund to userid=$refund_userid");
+
             my $promoid = $self->get_prop('selfpromo_refund_promoid');
-            my $refund_to        = LJ::load_userid($refund_userid);
+            LJ::Pay::SelfPromo->debug_msg("refund promoid=$promoid");
 
+            my $refund_to = LJ::load_userid($refund_userid);
+            LJ::Pay::SelfPromo->debug_msg(
+                "refund goes to user=" . $refund_to->username );
+
             my $promo = LJ::Pay::SelfPromo->current_entry_info($promoid);
 
             my $refund = $self->get_prop('selfpromo_refund');
             if ($refund) {
+                LJ::Pay::SelfPromo->debug_msg("crediting them");
+
                 # credit them:
                 LJ::Pay::Wallet->try_add( $refund_to, $refund );
                 LJ::Pay::Wallet::Log->log(
@@ -120,6 +144,8 @@
                     'status'   => LJ::Pay::Wallet::Log::STATUS_FINISHED,
                     'time_end' => time,
                 );
+
+                LJ::Pay::SelfPromo->debug_msg("successfully credited");
             }
 
             my $entry_url = $promo->entry_url;
@@ -130,6 +156,9 @@
                 'poster_cancel' => 'poster',
             };
 
+            LJ::Pay::SelfPromo->debug_msg(
+                "emailing them that someone bought the place out");
+
             # email them:
             LJ::Pay::SelfPromo->send_notification(
                 $refund_to, 'deactivate',
@@ -151,6 +180,8 @@
                     'notify_poster' => 1,
                 );
             }
+
+            LJ::Pay::SelfPromo->debug_msg("refund successful");
         }
     }
 
@@ -161,6 +192,10 @@
         my $remainder_to = LJ::load_userid($remainder_to_userid);
 
         if ($remainder_to) {
+            LJ::Pay::SelfPromo->debug_msg(
+                "sending the remainder of tokens to " .
+                $remainder_to->username );
+
             LJ::Pay::Wallet->try_add( $remainder_to, $remainder );
             LJ::Pay::Wallet::Log->log(
                 'userid'   => $remainder_to_userid,
@@ -184,11 +219,17 @@
         my $entry = $self->get_entry;
         my $poster = $entry->poster;
 
+        LJ::Pay::SelfPromo->debug_msg(
+            "setting the new active entry: " . $entry->url );
+
         my $cost = $self->get_amt * LJ::Pay::Wallet::EXCHANGE_RATE();
         LJ::Pay::SelfPromo->activate_entry( $entry, $cost, $rcpt_u );
 
+        LJ::Pay::SelfPromo->debug_msg("entry activated successfully");
+
         $email_subject = $ml->('selfpromo.notification.activate.subject');
 
+        LJ::Pay::SelfPromo->debug_msg("generating the emails");
         # Need to send second email if entry poster and recipient are different
         unless ( LJ::u_equals($poster, $rcpt_u) ) {
             $email_body = $ml->(
@@ -231,6 +272,8 @@
         );
     }
 
+    LJ::Pay::SelfPromo->debug_msg("delivery successful");
+
     return ( 1, $email_subject, $email_body );
 }
 

Modified: trunk/cgi-bin/LJ/Pay/SelfPromo.pm
===================================================================
--- trunk/cgi-bin/LJ/Pay/SelfPromo.pm	2012-01-23 12:05:56 UTC (rev 11340)
+++ trunk/cgi-bin/LJ/Pay/SelfPromo.pm	2012-01-23 15:03:53 UTC (rev 11341)
@@ -5,6 +5,9 @@
 use LJ::Pay::Wallet;
 use LJ::Pay::Wallet::Error qw(:codes);
 use LJ::Pay::SelfPromo::History;
+
+use Sys::Hostname qw();
+
 use Exporter;
 our @ISA = qw(Exporter);
 
@@ -116,32 +119,57 @@
 sub buyout {
     my ( $class, $entry, $promoter, $price ) = @_;
 
+    LJ::Pay::SelfPromo->debug_msg(
+        "buyout requested, " .
+        "entry => " . $entry->url . ", " .
+        "promoter => " . $promoter->username . ", " .
+        "price => $price"
+    );
+
     my $lock = $class->lock;
 
+    LJ::Pay::SelfPromo->debug_msg("lock acquired successfully");
+
     ## check entry
     do {
         my $reason;
+        LJ::Pay::SelfPromo->debug_msg("checking if the entry is eligible...");
+
         unless ( $class->is_entry_eligible( $entry, $promoter, \$reason ) ) {
+            LJ::Pay::SelfPromo->debug_msg("no it's not: $reason");
             $class->raise_error( ERROR_ENTRY_INELIGIBLE, $reason );
         }
+
+        LJ::Pay::SelfPromo->debug_msg("yes it is");
     };
 
     ## check price
     do {
+        LJ::Pay::SelfPromo->debug_msg("checking the price");
+
         my $price_additional = $price - $LJ::SELF_PROMO_CONF->{'min_cost'};
         if ( $price_additional % $LJ::SELF_PROMO_CONF->{'step'} ) {
+            LJ::Pay::SelfPromo->debug_msg("price is invalid: $price");
             $class->raise_error(ERROR_INVALID_PRICE);
         }
 
         my $min_price = $class->buyout_cost;
         unless ( $price >= $min_price ) {
+            LJ::Pay::SelfPromo->debug_msg(
+                "not enough money offered, need at least $min_price");
+
             $class->raise_error( ERROR_PRICE_INSUFFICIENT, $min_price );
         }
 
-        my $wallet_balance = LJ::Pay::Wallet->get_user_balance($promoter);
+        my $wallet_balance = int LJ::Pay::Wallet->get_user_balance($promoter);
         unless ( $wallet_balance >= $price ) {
+            LJ::Pay::SelfPromo->debug_msg(
+                "promoter doesn't actually have that much " .
+                "(has $wallet_balance, tried to buy out for $price)"
+            );
+
             $class->raise_error( ERROR_WALLET_INSUFFICIENT_FUNDS,
-                int $wallet_balance );
+                $wallet_balance );
         }
     };
 
@@ -150,6 +178,8 @@
     my $cart;
     do {
 
+        LJ::Pay::SelfPromo->debug_msg("creating the cart");
+
         # calculate how much money goes where for this item:
         # a part of it goes to the system, a part of it goes to the
         # user who purchased the selfpromo that was running before the
@@ -186,8 +216,13 @@
             }
         );
 
+        LJ::Pay::SelfPromo->debug_msg("cart created, setting the method");
+
         $cart->set_method( LJ::Pay::Method::Wallet->code );
+
+        LJ::Pay::SelfPromo->debug_msg("paying for the cart");
         LJ::Pay::Wallet->pay_for_cart( $cart->get_payid );
+        LJ::Pay::SelfPromo->debug_msg("paid successfully");
     };
 
     # deliver the cart synchronously, so that changes are applied
@@ -197,17 +232,34 @@
     # this part isn't supposed to throw any exceptions because
     # all the checks have been done before
     do {
+        LJ::Pay::SelfPromo->debug_msg("delivering the cart/items");
+        LJ::Pay::SelfPromo->debug_msg( "payid=" . $cart->get_payid );
+
         my ($item) = $cart->get_items;
 
+        LJ::Pay::SelfPromo->debug_msg( "piid=" . $item->get_piid );
+
         $cart->update( 'used'   => 'Y' );
         $item->update( 'status' => 'pend' );
 
+        LJ::Pay::SelfPromo->debug_msg(
+            "cart and item updated to be ready for delivery");
+
+        local $SIG{'__WARN__'} = sub {
+            my @messages = @_;
+            LJ::Pay::SelfPromo->debug_msg( "delivery warning: ", @messages );
+            warn @messages;
+        };
+
         my $deliver_res = $item->deliver( $cart, time, sub { } );
         unless ($deliver_res) {
+            LJ::Pay::SelfPromo->debug_msg("delivery failed");
             die "delivering item failed, see error log for details";
         }
     };
 
+    LJ::Pay::SelfPromo->debug_msg("all done");
+
     LJ::Pay::SelfPromo::History->update();
 
     return $cart;
@@ -729,6 +781,9 @@
 sub create_shop_cart {
     my ( $class, $opts ) = @_;
 
+    LJ::Pay::SelfPromo->debug_msg(
+        "create_shop_cart called: " . LJ::compact_dumper($opts) );
+
     my $cart = LJ::Pay::Payment::new_cart( $opts->{'cart_owner'} );
 
     my $it = LJ::Pay::Payment::PayItem->new_memonly(
@@ -759,6 +814,12 @@
         $it->set_prop( 'selfpromo_ditemid'   => $entry->ditemid );
     }
 
+    LJ::Pay::SelfPromo->debug_msg(
+        "create_shop_cart successful, " .
+        "payid=" . $cart->get_payid . ", " .
+        "piid=" . $it->get_piid
+    );
+
     return $cart;
 }
 
@@ -939,6 +1000,21 @@
     return LJ::statushistory_add( $promoter, $systemu, 'selfpromo', $message );
 }
 
+sub debug_msg {
+    my ( $class, @args ) = @_;
+
+    return unless LJ::is_enabled('selfpromo_debug');
+
+    my $hostname = Sys::Hostname::hostname();
+    my $time     = localtime;
+
+    my $msg = join( '',
+        "[shop/selfpromo, pid=$$, host=$hostname, time=$time] ", @args );
+
+    my ( $package, $filename, $line, $sub ) = caller(1);
+    warn "$msg in sub ${package}::${sub} at $filename line $line\n";
+}
+
 package LJ::Pay::SelfPromo::Promo;
 
 use base qw( Class::Accessor );
@@ -992,41 +1068,58 @@
 
 package LJ::Pay::SelfPromo::Lock;
 
-my $locked = 0;
-
 sub new {
     my ($class) = @_;
 
-    return if $locked;
+    LJ::Pay::SelfPromo->debug_msg("trying to acquire lock");
 
-    die "Can't get lock"
-        unless LJ::get_lock( LJ::get_db_writer(), 'global', 'selfpromo' );
+    if ( $LJ::REQ_GLOBAL{'selfpromo_locked'} ) {
+        LJ::Pay::SelfPromo->debug_msg("... already got it, skipping");
+        return;
+    }
 
-    $locked = 1;
+    my $lock_result =
+        LJ::get_lock( LJ::get_db_writer(), 'global', 'selfpromo' );
+
+    unless ($lock_result) {
+        LJ::Pay::SelfPromo->debug_msg(
+            "LJ::get_lock returned false, throwing an exception" );
+        die "Can't get lock";
+    }
+
+    LJ::Pay::SelfPromo->debug_msg("locked successfully");
+
+    $LJ::REQ_GLOBAL{'selfpromo_locked'} = 1;
     return bless {}, $class;
 }
 
 sub DESTROY {
     my ($self) = @_;
 
+    LJ::Pay::SelfPromo->debug_msg("releasing the lock");
+
     ## warning: this code may be called during exception "stack unwind" step.
     ## if original exception ($@) is not saved, it will be lost.
     local $@;
 
     LJ::release_lock( LJ::get_db_writer(), 'global', 'selfpromo' );
 
-    $locked = 0;
+    $LJ::REQ_GLOBAL{'selfpromo_locked'} = 0;
 }
 
 sub taken {
     my ($class) = @_;
-    return LJ::lock_taken( LJ::get_db_writer(), 'global', 'selfpromo' );
+    my $result = LJ::lock_taken( LJ::get_db_writer(), 'global', 'selfpromo' );
+    LJ::Pay::SelfPromo->debug_msg("lock taken => $result");
+    return $result;
 }
 
 sub taken_elsewhere {
     my ($class) = @_;
 
-    return !$locked && $class->taken;
+    my $result = ! $LJ::REQ_GLOBAL{'selfpromo_locked'} && $class->taken;
+    LJ::Pay::SelfPromo->debug_msg("lock taken elsewhere => $result");
+    return $result;
 }
 
 1;

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