abhishek
abhishek

Reputation: 31

Scala wait of list of future to execute

Hi I am trying to process data in a file.

This the code I am using below.

I have a list of Futures and trying to get the output from these futures.

Everything is fine but the last line of return is executing before OnSuccess.

How can I change that behaviour without having a blocking operation.

def processRow(rowNumber: Int, row: String, delimiter: String, rules: List[Rule]): RowMessage = {
var cells = row.split(delimiter)
var passedRules = new ListBuffer[RuleResult]()
val failedRules = new ListBuffer[RuleResult]()
val rulesFuture = rules.map {
  i => Future {
    val cells = row.split(delimiter);
    //some processing....
  }
}
val f1 = Future.sequence(rulesFuture)
f1 onComplete {
  case Success(results) => for (result <- results) (result.map(x => {
    if (x.isPassFailed) {
      passedRules += x
    }
    else {
      failedRules += x
    }
  }))
  case Failure(t) => println("An error has occured: " + t.getMessage)
}
return new RowMessage(passedRules.toList,   failedRules.toList)
}

Upvotes: 0

Views: 133

Answers (1)

Łukasz
Łukasz

Reputation: 8663

You can't avoid blocking and return a plain RowMessage. You need to return a Futureas well.

def processRow(rowNumber: Int, row: String, delimiter: String, rules: List[Rule]): Future[RowMessage] = {
  val cells = row.split(delimiter)
  Future.traverse(rules) { i =>
    Future {
      //some processing....
    }
  } map { results =>
    val (passed, failed) = results.partition(_.isPassFailed)
    new RowMessage(passed, failed)
  }
}

Also think about your algorithm to avoid mutable state, especially when you change it from different Futures.

Future.traverse is equivalent of your map + Future.sequence. Then instead of onComplete, just map your Future to modify the list. You can split it easly using partition instead of what you've been doing.

You don't need to use return, in fact you shouldn't unless you know what you are doing.

Btw isPassFailed doesn't sound like a reasonable method name to me, especially considering that when it's true you are adding it to passed rules.

Upvotes: 1

Related Questions