Reputation: 42100
This is a follow-up to my old question. Suppose I need to invoke a REST service both synchronously and asynchronously. In the synchronous case I would like to do it on the caller thread without taking other threads from the pool.
I would like to write my business logic only once and reuse it in the both cases. The business logic consists of building a request and handling the response.
I would like also to compose REST invocations, as if in "invoke service A and then service B and then service C"
How would you do it in Scala ?
Upvotes: 3
Views: 342
Reputation: 1849
This should run in the current thread...
{
val currentThreadEx = new AbstractExecutorService {
override def execute(r: Runnable) { r.run }
override def shutdownNow(): java.util.List[Runnable] = new java.util.ArrayList[Runnable]()
override def shutdown() {}
override def isTerminated = false
override def isShutdown = false
override def awaitTermination(timeout: Long, unit: TimeUnit) = false
}
implicit val exContext = ExecutionContext.fromExecutor(currentThreadEx)
val f = Future {
10 + 1
}
println(Await.result(f, 1 seconds))
}
This will run on the default executor...
{
import ExecutionContext.Implicits.global
val f = Future {
10 + 1
}
println(Await.result(f, 1 seconds))
}
As you can see, you can use ExecutorService as the abstraction point.
Or you can use a function written in terms of Monads, and then you can bind those operations together without dealing with the context (i.e. Future).
def op1[M[_]: Monad](i: Int)(j: Int): M[Int] = {
Monad[M].point { i * j }
}
println(Monad[Id].point(10) >>= op1[Id](10))
println((Future { 10 } >>= op1[Future](10)).run)
Upvotes: 2