Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Future inside DBIOAction composition in slick 3?

Slick 3 offers DBIOAction composition by using flatMap method. Also, we can do some calculations in back-end between two DBIOActions. That's works fine in most cases, but what I should do when calculations result is in the monad like Future? There is code with blocking way:

val fooQuery = TableQuery[FooTable]
val barQuery = TableQuery[BarTable]

def requestService(content: Iterable[String]): Future[Iterable[Long]] = ???

def modify(ids: Iterable[Long], change: String) = {

    val query = fooQuery.filter(_.id inSet ids).result.flatMap{ fooSeq =>
        val content = fooSeq.map(_.contentField)
        val requestServiceFuture = requestService(content)

        val serviceResult = Await.result(requestServiceFuture, 1.minute)
        barQuery.filter(_.id inSet serviceResult).delete //or other action
    }
    db.run(query.transactionally)
} 

Is there way to perform this code asynchronously, without Await?

like image 836
StopKran Avatar asked Oct 19 '25 09:10

StopKran


1 Answers

You can create DBIO from Future using DBIOAction.from and then compose with other DBIOs using flatMap

val query = for {
    fooSeq <- fooQuery.filter(_.id inSet ids).result
    content = fooSeq.map(_.contentField)
    serviceResult <- DBIOAction.from(requestService(content))
    result <- barQuery.filter(_.id inSet serviceResult).delete
} yield result

db.run(query.transactionally)

http://slick.lightbend.com/doc/3.1.1/api/index.html#slick.dbio.DBIOAction$

like image 128
Łukasz Avatar answered Oct 21 '25 22:10

Łukasz