How can I run methods from inside a specific ExecutionContext
only?
For example, consider this code:
trait SomeTrait {
private var notThreadSafe = 0 // mutable var!
def add(i: Int) = ???
def subtract(i: Int) = ???
}
This code is only correct if methods add
and subtract
are called from the same thread only. What are the ways to make those methods always use a specific ExecutionContext
(which would make sense if there is exactly 1 worker in the EC)? Any easy ways?
To get a grasp on the question, here are some example answers:
Answer1: wrap the body of all methods in Future.apply
, like this:
class SomeClass {
private implicit val ec: ExecutionContext = ???
private var notThreadSafe = 0
def add(i: Int) = Future {
???
}
def subtract(i: Int) = Future {
???
}
}
Answer2: use an akka
actor, convert all methods to incoming actor messages and use the ask pattern to work with the actor. If you don't mess things up intentionally, all methods will run from your actor-s EC.
Answer3: maybe write a macro function that would convert a trait to its Future-ized version? Like expanding this code:
MyTrickyMacro.futurize(underlying: SomeTrait)(ec)
to this:
class MacroGeneratedClass(underlying: SomeTrait)(implicit ec: ExecutionContext) {
def add(i: Int) = Future(underlying.add(i))
def subtract(i: Int) = Future(underlying.subtract(i))
}
Now, I think Answer1 is generally OK, but prone to errors and a bit of boilerplate. Answer2 still requires boilerplate code to be written, forces you to create case classes to contain function arguments and requires akka. And I didn't see any implementations Answer3.
So... Is there an easy way to do that?