ps0604
ps0604

Reputation: 1071

Running queries in parallel in Slick 3.x

I have the following code in Slick 3.x/Play for Scala:

  val filters = TableQuery[FilterDB]
  val action6 = filters.filter(_.sk === sk).result
  val future6 = db.run(action6)
  Await.result(future6, Duration.Inf)

  val tags = TableQuery[TagSelectionDB]
  val action7 = tags.filter(_.sk === sk).result
  val future7 = db.run(action7)
  Await.result(future7, Duration.Inf)

Note that these two queries will run sequentially. Is it possible to run them in parallel, if yes, how? Also, is the fact that queries run in parallel in Scala/Slick will also run in parallel in the database engine?

Upvotes: 0

Views: 1679

Answers (1)

Nagarjuna Pamu
Nagarjuna Pamu

Reputation: 14825

Yes. you can run queries in parallel, but how they run inside the database cannot be controlled by slick. Database tries to run the queries in parallel as much as possible unless there are any data dependencies, locks acquired on tables and rows etc. Here is the function which does the job.

val f1 = db.run(action6)

val f2 = db.run(action7)

val result = f1 zip f2 

Await.result(result, Duration.Inf) // await only if you want to see the results in a blocking manner. Instead compose the future to produce results.

Note that f1 and f2 run parallely as they are created independently. But you have to wait for the result future to complete.

In case you have huge list of queries to execute then parallely function can help you ease you work.

parallely uses Future.traverse to run the future of db queries and makes result available inside a list in order.

def parallely[T](dbios: DBIO[T]*): Future[List[Try[T]]] = {

 Future.traverse(dbios.map(db.run(_))) { f => 
  f.map(Success(_))
   .recover { case th => Failure(th)} }
}

Usage:

val result = parallely(action6, action7)

//wait if you want to see the result in a blocking manner.
//Blocking is not good idea. So compose the resultant future to produce results based on db results.

Upvotes: 2

Related Questions