unleashed
unleashed

Reputation: 925

Scala 2 futures containing api calls race condition

I've defined some API calls in Futures that make API calls to Mashery and Stripe

 val stripeFuture = Future { // api call }
 val masheryFuture = Future { //api call }

For the stripeFuture -The main logic is to set the stripeCustomerId on a Client object within the onSuccess block

  stripeFuture onSuccess {
       //client.stripeCustomerId
  }

I've wrapped up the API calls in a for-comprehension similar to the example in Futures and Promises

  val apiCalls = for {

      masheryInfo <- masheryFuture
      stripeCustomer <- stripeFuture
    }

There is a rollback if one of the API calls fail

  apiCalls onFailure {
      case pse: MasheryException => {
        // delete stripe customer id
   }

   case e: StripeException => {
       //delete mashery api key
   }

The problem is when the call to Mashery fails 'masheryFuture', I want to rollback 'get the stripe id' from the Client object but there is a around a 1 second delay til that call finishes and it doesn't set the stripeCustomerId until it hits the onSuccess block so within the ase pse: MasheryException => { } block, client.getstripeCustomerId returns null.

Is there a way of getting around this race condition for both of the API calls

Upvotes: 1

Views: 371

Answers (1)

som-snytt
som-snytt

Reputation: 39577

Use Future.andThen.

The doc:

Applies the side-effecting function to the result of this future, and returns a new future with the result of this future.

This method allows one to enforce that the callbacks are executed in a specified order.

for (f <- Future(x).andThen { y }) etc.

Update:

for (f <- Future(x) andThen {
    case Success(x) => use(x)
    case _ => // ignore
  }) yield result

Upvotes: 5

Related Questions