Reputation: 189
Is there an idiomatic way to deal with side-effecting scala.concurrent.Future
whose result is not really needed in the caller (i.e. neither success nor failure will be necessary to calculate the calling method's return value)? For example,
object XYZ {
def log(s: String): Future[Unit] = ???
}
Is it correct to simply call XYZ.log("xyz")
without any callbacks and proceed with the really important tasks? Won't this orphan Future be considered code smell? Any chance for it to be garbage collected before it is executed?
Upvotes: 2
Views: 190
Reputation: 48430
When we have such Future
s which are not part of main business logic but executed for their side effect, that is, represent a separate concern such as logging, then consider running them on a separate dedicated execution context. For example, create a separate pool with
val numOfThreads = 2
val threadPoolForSeparateConcerns = Executors.newFixedThreadPool(numOfThreads, (r: Runnable) => new Thread(r, s"thread-pool-for-separate-concerns-thread-${Random.nextInt(numOfThreads)}"))
val separateConcernsEc = ExecutionContext.fromExecutor(threadPoolForSeparateConcerns)
and then make sure to pass it in when running separate concerns
object XYZ {
def log(s: String, ec: ExecutionContext): Future[Unit] = ???
}
XYZ.log("Failed to calculate 42", separateConcernsEc)
By separating main business logic thread pool, from thread pool for side-concerns, we minimise the chances of breaking main business logic through things like resource starvation etc.
Upvotes: 1
Reputation: 170899
Won't this orphan Future be considered code smell?
Not any more than any other discarded non-Unit
value. Note that some people do consider any discarded value to be a code smell, which is why -Ywarn-value-discard
and NonUnitStatements
wart exist.
Any chance for it to be garbage collected before it is executed?
The Future
object itself might be garbage collected, but it will submit a task to a thread pool which won't be (because the pool holds a reference to the task). Except cases like
def log(s: String): Future[Unit] = Future.just(())
of course.
Upvotes: 2