2016-09-13 11:52:27 -04:00
|
|
|
package controllers;
|
|
|
|
|
|
|
|
import akka.actor.ActorSystem;
|
2016-10-04 11:54:59 -04:00
|
|
|
|
2016-09-13 11:52:27 -04:00
|
|
|
import javax.inject.*;
|
2016-10-04 11:54:59 -04:00
|
|
|
|
2016-09-13 11:52:27 -04:00
|
|
|
import play.*;
|
|
|
|
import play.mvc.*;
|
2016-10-04 11:54:59 -04:00
|
|
|
|
2016-09-13 11:52:27 -04:00
|
|
|
import java.util.concurrent.Executor;
|
|
|
|
import java.util.concurrent.CompletableFuture;
|
|
|
|
import java.util.concurrent.CompletionStage;
|
|
|
|
import java.util.concurrent.TimeUnit;
|
2016-10-04 11:54:59 -04:00
|
|
|
|
2016-09-13 11:52:27 -04:00
|
|
|
import scala.concurrent.duration.Duration;
|
|
|
|
import scala.concurrent.ExecutionContextExecutor;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This controller contains an action that demonstrates how to write
|
|
|
|
* simple asynchronous code in a controller. It uses a timer to
|
|
|
|
* asynchronously delay sending a response for 1 second.
|
|
|
|
*
|
|
|
|
* @param actorSystem We need the {@link ActorSystem}'s
|
2016-10-04 11:54:59 -04:00
|
|
|
* {@link Scheduler} to run code after a delay.
|
|
|
|
* @param exec We need a Java {@link Executor} to apply the result
|
|
|
|
* of the {@link CompletableFuture} and a Scala
|
|
|
|
* {@link ExecutionContext} so we can use the Akka {@link Scheduler}.
|
|
|
|
* An {@link ExecutionContextExecutor} implements both interfaces.
|
2016-09-13 11:52:27 -04:00
|
|
|
*/
|
|
|
|
@Singleton
|
|
|
|
public class AsyncController extends Controller {
|
|
|
|
|
|
|
|
private final ActorSystem actorSystem;
|
|
|
|
private final ExecutionContextExecutor exec;
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
public AsyncController(ActorSystem actorSystem, ExecutionContextExecutor exec) {
|
2016-10-04 11:54:59 -04:00
|
|
|
this.actorSystem = actorSystem;
|
|
|
|
this.exec = exec;
|
2016-09-13 11:52:27 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* An action that returns a plain text message after a delay
|
|
|
|
* of 1 second.
|
2016-10-04 11:54:59 -04:00
|
|
|
* <p>
|
2016-09-13 11:52:27 -04:00
|
|
|
* The configuration in the <code>routes</code> file means that this method
|
|
|
|
* will be called when the application receives a <code>GET</code> request with
|
|
|
|
* a path of <code>/message</code>.
|
|
|
|
*/
|
|
|
|
public CompletionStage<Result> message() {
|
|
|
|
return getFutureMessage(1, TimeUnit.SECONDS).thenApplyAsync(Results::ok, exec);
|
|
|
|
}
|
|
|
|
|
|
|
|
private CompletionStage<String> getFutureMessage(long time, TimeUnit timeUnit) {
|
|
|
|
CompletableFuture<String> future = new CompletableFuture<>();
|
|
|
|
actorSystem.scheduler().scheduleOnce(
|
2016-10-04 11:54:59 -04:00
|
|
|
Duration.create(time, timeUnit),
|
|
|
|
() -> future.complete("Hi!"),
|
|
|
|
exec
|
2016-09-13 11:52:27 -04:00
|
|
|
);
|
|
|
|
return future;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|