Scala Futures in Play Actions (fire and forget best practice)

1,009 views
Skip to first unread message

Bruno Batarelo

unread,
Aug 13, 2015, 12:23:04 PM8/13/15
to play-framework
Hello all,

  I'm interested in getting a confirmation that a fire and forget future launched within action will always complete. Let me clarify.
Assume this code in console application:

def main(args: Array[String]): Unit = {

  futureWork
  println("end")
}

def futureWork = Future{
  println("entered future")
  Thread.sleep(2000)
  println("finished computation")
}


Usually output will be:
entered future
end

and that makes sense. Basically process reached its end before other thread finished its work and it got terminated with the application.

Now if we try doing that in the action:

def index = Action { implicit request =>
  futureWork
  Ok("")
}

http client will receive OK and console output will be:
entered future
finished computation

Everything seems right. Also, future callback is always (in my test case though not guaranteed) executed on a future thread.

With hose samples, I can only confirm that usually futures complete after the action was already finished and that's the behavior that I need. My business requirement is that if process (within the action) reaches certain point, all tasks afterwards can fail and that will be logged somewhere, but overall request was successful. My question is, am I guaranteed that future won't die (similar to console sample) because the action from the launching thread has been "long time" gone?

Thanks,
Bruno

v6ak

unread,
Aug 13, 2015, 3:16:48 PM8/13/15
to play-framework
I am afraid you can't be guaranteed that futures will not die. But that will depend…

First, it will depend on the ExecutionContext you are using. If the ExecutionContext is backed by a daemon thread, Futures can “die” when the application terminates. If the ExecutionContext is backed by a non-daemon thread, Futures should not die this way on a normal exit. (Note that using non-daemon threads for ExecutionContext complicates VM shutdown somehow: they have to be shut down manually, maybe when some signal is received.) However…

Second, it depends what types of exit you consider. When you consider power outage, OutOfMemoryError, JVM crash, kernel panic, Linux OOM kill, kill -9 and so on, Futures can't survive that. Depending on your business requirements, you may need to consider using some durable message queue or something like that. You put the task to the queue and wait until it is confirmed to be stored to some durable storage. (You can use SQL DB – while this is probably not the most efficient solution, it should work…) After you have saved the message into the queue, you will send the Ok to the client. Then, there will be some other process (maybe on a different machine) that will consume the tasks.

But suitability of such solution may depend on the type of tasks. Imagine there is a power outage (or some other kind of interuption) after the task is processed, but before the task is deleted from the queue. If the tasks are idempotent (e.g. statistics recalculation), it is clearly OK to repeat them. If the task sends an e-mail, this is not so good, but sending double e-mail is some rare cases can be a negligible issue. In some cases, the task can be of a truly transactional nature and you will have to care about that, because doing such task twice has unwanted consequences. But… but this is far beyond the original question.

Regards,
Vít Šesták 'v6ak'

Bruno Batarelo

unread,
Aug 13, 2015, 5:44:26 PM8/13/15
to play-framework
Wow, you took the problem much further then I actually needed. I am in scope of play framework and its default execution context :) I don't currently care about failed hardware or power outages. My question was related to anatomy of play application and scala futures. So let me rephrase: am I guaranteed that future initialized from Action will always survive Action return (with whichever completion status)?

Cheers,
Bruno

Mirco Dotta

unread,
Aug 14, 2015, 2:52:36 AM8/14/15
to play-fr...@googlegroups.com
The answer to your question is “Yes" :)

----------------
Mirco Dotta - @mircodotta

Typesafe – Build reactive apps!

-- 
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/90652f4c-307c-4805-9f30-9ca8577a4cfa%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

signature.asc

Christian Schmitt

unread,
Aug 14, 2015, 3:23:53 AM8/14/15
to play-framework
Wouldn't it be better to sent the things to a Actor and start the future there?

Bruno Batarelo

unread,
Aug 14, 2015, 7:01:57 AM8/14/15
to play-framework
What I'm having is a simple case and actors would be somewhat an overkill on several levels. On the other hand, if I was using actors, I'd probably launch an actor instead of future or create an actor that would handle queue of jobs instead of futures.

Bruno

Bruno Batarelo

unread,
Aug 14, 2015, 7:02:31 AM8/14/15
to play-framework
Tnx! :)

B
Reply all
Reply to author
Forward
0 new messages