3

I have set up a rails API for my iOS application. We have a group split feature that allows people to invite people to their group and split the entire bill equally. It is currently implemented and working well but as the group size grows the time to process the transactions really slows down (due to them being in a loop rather then all at once).

I'm curious if anyone else has tackled something similar or has any resources to point me in the right direction for something like this. Currently we are placing holds on each of the group members cards and if all of the holds are successful we capture them. We do this to ensure no one in the groups card bounces, if we went straight to debiting the cards we could be liable for chargebacks if someones card did bounce. We're using the Balanced Payments ruby client.

I have seen the celluloid gem or sidekiq. I usually do all of the iOS work but we have been having quite a hard time getting someone good to do the API and I decided to give it a try for this app, so far so good until I encountered this problem.

@booking.group.group_members.each do |group_member|
        credit_card = CreditCard.find(group_member.credit_card_id)
        customer = Balanced::Account.find(group_member.user.customer_uri)

        booking = Booking.create(:venue_id => @venue.id,
                              :user_id => group_member.user_id,
                              :group_id => @booking.group_id,
                              :subtotal => @booking.subtotal / @group_count,
                              :total => @booking.total / @group_count,
                              :gratuity_fee => @booking.gratuity / @group_count,
                              :credit_card_fee => @booking.fees / @group_count,
                              :credit_card_id => group_member.credit_card_id,
                              :receipt_id => @booking.id,
        )

        begin
          hold = customer.hold({:amount => ((booking.subtotal + booking.booking_fee + booking.gratuity_fee  + booking.credit_card_fee) * 100).to_int,
                                :on_behalf_of_uri => @merchant_uri,
                                :appears_on_statement_as => "...",
                                :source_uri => credit_card.credit_card_uri}
          )

        rescue Balanced::Error => error
            #handle errors
            render json: error.description, status: error.status_code
          end
        end
      end

This is how I am placing the holds on each of the cards. Does anyone have any ideas on how I could process all these in parallel rather then sequentially. I know sidekiq or celluloid could handle something similar pretty easy but I'm worried if an error occurs while processing the payment and how to handle them if they're being processed all at one time.

templeman15
  • 799
  • 8
  • 14

1 Answers1

1

If you've made your Rails app thread-safe, you could just call Thread.new and process each customer in a separate thread. Then when you join the threads you can check for errors and carry on.

More on how to work with threads here.

If groups can get very big, you'll probably want to limit the amount of concurrent threads. I usually keep the threads in an array, and if it reaches a size limit I join the first one before continuing.

pcarranzav
  • 215
  • 2
  • 7