mark: A photo of Mark kneeling on top of the Taal Volcano in the Philippines. It was a long hike. (Default)
Mark Smith ([staff profile] mark) wrote in [site community profile] changelog2009-05-02 07:06 am

[dw-free] Found a weird error where sometimes carts end up with items having the same ID, leading to

[commit: http://hg.dwscoalition.org/dw-free/rev/0d02b33c653b]

Found a weird error where sometimes carts end up with items having the same
ID, leading to issues issuing codes. This now tries to renumber the items
to ensure we can process a cart. It'd be best to fix the issue that causes
this, but this works around it for existing carts.

Patch by [staff profile] mark.

Files modified:
  • bin/worker/paidstatus
--------------------------------------------------------------------------------
diff -r 847dc1707b04 -r 0d02b33c653b bin/worker/paidstatus
--- a/bin/worker/paidstatus	Sat May 02 06:00:48 2009 +0000
+++ b/bin/worker/paidstatus	Sat May 02 07:06:53 2009 +0000
@@ -305,10 +305,28 @@ sub scan_cart {
         unless $cart->has_items;
 
     # try to apply each item
-    my $unapplied = 0;
+    my ( $unapplied, %saw_ids ) = ( 0 );
     $log->( 'Iterating over items.' );
     foreach my $item ( @{ $cart->items } ) {
-        $log->( 'Found item %s.', $item->short_desc );
+        $log->( 'Found item [%d] %s.', $item->id, $item->short_desc );
+
+        # rare case where we've found the cart generating items with the same
+        # id, leading to failures in sending invite codes
+        while ( exists $saw_ids{$item->id} ) {
+            if ( $item->applied ) {
+                $log->( 'Item id duplicate, but item safely applied.  Ignoring dupe id.' );
+                next;
+            }
+
+            # this item has NOT been applied, so renumber it
+            $item->id( $item->id + 1 );
+            $log->( 'Item id already found, renumbering to %d.', $item->id );
+        }
+
+        # record the id in our list so we know we've seen it
+        $saw_ids{$item->id} = 1;
+
+        # this is the normal 'bail' point for already applied items
         if ( $item->applied ) {
             $log->( 'Item already applied.' );
             next;
--------------------------------------------------------------------------------