JavaAsync - opensas/Play20Es GitHub Wiki
Esta página todavía no ha sido traducida al castellano. Puedes ayudarnos con la tarea simplemente presionando el botón
Edit Page. Para más información puedes leer esta guía para el traductor. Aquí puedes ver cuánto nos falta para terminar la traducción.
Hasta ahora, eramos capaces de procesar el resultado para enviar al cliente web directamente. Esto no siempre es el caso: el resultado puede depender de un procesamiento costoso o una llamada a Web Service muy larga.
Debido a la forma en que Play 2.0 funciona, el código de acción debe ser lo más rápido posible (e.j. non-blocking). Así que, que se debería enviar como resultado si aún no hemos sido capaces de procesarlo? La respuesta debe ser una promesa de un resultado!
Una promesa de resultado Promise<Result> eventualmente será redimida con un valor de tipo Result. Al entregar un Promise<Result> en vez de un Result normal, somos capaces de procesar el resultado rápidamente sin bloquear nada. Play entonces entregará el resultado tan rápido como la promesa sea redimida.
El cliente web será bloqueado mientras espera por la respuesta pero nada será bloqueado en el servidor, y los recursos del servidor podrán ser usados para responder a otros clientes.
Para crear un Promise<Result> necesitamos otra promesa primero: la promesa que nos dará el valor que debemos procesar:
Promise<Double> promiseOfPIValue = computePIAsynchronously();
Promise<Result> promiseOfResult = promiseOfPIValue.map(
new Function<Double,Result>() {
public Result apply(Double pi) {
return ok("PI value computed: " + pi);
}
}
);
Nota: Escribir composiciones funcionales en Java es bastante extenso (verbose) en estos momentos, pero debería mejorar cuando Java de soporte a notación lambda.
Los métodos asíncronos del API de Play 2.0 entregan un Promise. Este es el caso cuando se está invocando un Web Service externo usando el API play.libs.WS, o si está usando Akka para programar tareas asíncronas o para comunicarse con actores usando play.libs.Akka.
Una manera simple de ejecutar un bloque de código de manera asíncrona y obtener un Promise es usar los métodos utilitarios de play.libs.Akka:
Promise<Integer> promiseOfInt = Akka.future(
new Callable<Integer>() {
public Integer call() {
intensiveComputation();
}
}
);
Nota: Aquí, el método de procesamiento intensivo se ejecutará en otro Thread. También es posible ejecutarlo remotamente en un cluster de servidores utilizando Akka remote.
Mientras usábamos Results.Status hasta ahora, para enviar un resultado asíncrono debemos usar Results.AsyncResult que envuelva el resultado original:
public static Result index() {
Promise<Integer> promiseOfInt = Akka.future(
new Callable<Integer>() {
public Integer call() {
intensiveComputation();
}
}
);
async(
promiseOfInt.map(
new Function<Integer,Result>() {
public Result apply(Integer i) {
return ok("Got result: " + i);
}
}
)
);
}
Nota:
async()es un método utilitario que construye unAsyncResulta partir de unPromise<Result>.
Next: Streaming HTTP responses