For-comprehension semi-parallel calls in scala

Viewed 150

I want to make first call in seq to next ones but then next 10 calls parallel to each other using Scala's futures. I dont want to program map flatmaps or for inside for comprehensions as they'll add on to unreadibility. Is it possible with one for comprehension.

reference code:

val fcaAndFplAccountDetails  = getFcaAndFplAccount(fplId)
def orgDetailsIO(orgId:Int)  = getOrgDetails(orgId)
def unbilledTxns(orgid: Int) = getUnbilledTxns(orgId)
for {
      accDetails   <- fcaAndFplAccountDetails
      orgDetails   <- orgDetailsIO(accDetails.orgId)
      unbilledTxns <- unbilledTxnsIO(accDetails.orgId)
      ... other calls that depend on org id
    } yield { ... further computations }

Can the calls after fcaAndFplAccountDetails be parallelized within the comprehension?

2 Answers

Perhaps follow a generator with a value definition using equals symbol for the calls that should execute in parallel

for {
  accDetails    <- fcaAndFplAccountDetails
  orgDetailsF   = orgDetailsIO(accDetails.orgId)
  unbilledTxnsF = unbilledTxnsIO(accDetails.orgId)
  orgDetails    <- orgDetailsF
  unbilledTxns  <- unbilledTxnsF 
} yield { ... further computations }

or convey the idea with Applicative

import cats.implicits._

fcaAndFplAccountDetails.flatMap { accDetails =>
  (
    orgDetailsIO(accDetails.orgId),
    unbilledTxnsIO(accDetails.orgId)
  ).mapN((orgDetails, unbilledTxns) => {
    ... further computations  
  }
}

There must be dozens of options but one would be:

  val fcaAndFplAccountDetails : Future[Int] = ???
  def orgDetailsIO(orgId:Int)  : Future[_] = ???
  def unbilledTxns(orgid: Int) : Future[_] = ???
  for {
    accDetails   <- fcaAndFplAccountDetails
    (orgDetails, unbilledTxns)   <- Future.sequence(List(orgDetailsIO(accDetails), unbilledTxns(accDetails))).map(el => (el(0), el(1)))
} yield ()

You could use Future.traverse too

Related