2
votes

I have a simple Play application where a controller action calls model method which does some calculations and returns the result. What I need is action response to be delayed randomly between 1-5 seconds. I have little experience with Akka, but I don't know how to accomplish what I need.

Example controller:

package controllers

import scala.util.Random    
import play.api._
import play.api.mvc._

import models.MyModel

object Application extends Controller {

    def calculate = Action { implicit request =>

        val result = MyModel.calculate()
        val delay = Random.nextInt(6)

        //This response must be delayed somehow
        Ok(result)

    }

}

Example model:

package models

object MyModel {

    def calculate = {

        //calculation happens here

    }

}

UPDATE - SOLUTION senia's answer is working, but with deprecation warning. This code agrees with Play 2.2.1:

import play.api.libs.concurrent.Promise
import play.api.libs.concurrent.Execution.Implicits.defaultContext

def calculate = Action.async {

    val result = MyModel.calculate()
    val delay = Random.nextInt(6)
    val delayed = Promise.timeout(result, delay.second)
    delayed.map(Ok(_))

}
1

1 Answers

3
votes

See Handling asynchronous results/Handling time-outs in play framework documentation.

def calculate = Action.async { implicit request =>

  import play.api.libs.concurrent.Execution.Implicits.defaultContext
  import scala.concurrent.duration._

  val result = MyModel.calculate()
  val delay = Random.nextInt(6)

  val delayed = play.api.libs.concurrent.Promise.timeout(result, delay.seconds)

  delayed.map{Ok(_)}

}