¡La versión 2.0 de Play ya está lista! Ayúdanos a traducir la documentación de la útlima versión y sigue nuestro progreso.

Manuales, tutoriales & referencias

Consulte

Contenidos

Elija la versión

Buscar

Busque con google

Libros

Jobs Asincrónicos

Dado que Play es un framework de aplicaciones web, la mayor parte de la lógica de la aplicación es llevada a cabo por controladores en respuesta a solicitudes HTTP.

Pero a veces necesitas ejecutar parte de la lógica de la aplicación fuera de cualquier request HTTP. Esto puede ser útil para tareas de inicialización, de mantenimiento, o para ejecutar tareas largas sin bloquear el pool de ejecución de los pedidos HTTP.

Los Jobs, o tareas, son gestionados completamente por el framework. Esto quiere decir que Play se encargará de todo el tema de conexión a la base de datos, el gestor de entidades JPA, el control de la sincronización y las transacciones. Para crear un job basta con extender la clase play.jobs.Job.

package jobs;
 
import play.jobs.*;
 
public class MyJob extends Job {
    
    public void doJob() {
        // ejecutar aqui la lógica de la aplicación ...
    }
    
}

A veces precisará crear jobs que retornen un resultado. En estos casos tendrá que sobrecargar el método doJobWithResult().

package jobs;
 
import play.jobs.*;
  
public class MyJob extends Job<String> {
    
    public String doJobWithResult() {
        // ejecutar aqui la logica de la aplicacion ...
        return result;
    }
    
}

Aquí el uso de String es sólo un ejemplo. Por supuesto un job puede devolver cualquier tipo de objeto.

Jobs de arranque (Bootstrap)

Los jobs de arranque (bootstrap jobs) son ejecutados por Play al iniciar la aplicación. Para indicarle al framework que se trata de un job de arranque, basta añadir la anotación @OnApplicationStart.

import play.jobs.*;
 
@OnApplicationStart
public class Bootstrap extends Job {
    
    public void doJob() {
        if(Page.count() == 0) {
            new Page("root").save();
            Logger.info("Se ha creado una pagina principal.");
        }
    }
    
}

No necesita devolver un resultado. Incluso si lo hace, el resultado se perderá.

Por defecto, todos los jobs anotados con @OnApplicationStart se ejecutarán secuencialmente. Cuando se terminen todos los jobs, la aplicación está lista para empezar a procesar las request que lleguen al servidor.

Si desea que sus jobs inicien junto con la aplicación, pero quiere empezar a procesar los request inmediatamente, puede anotar el job con: @OnApplicationStart(async=true). De esta forma el job se iniciará en background cuando arranque la aplicación. Todos los jobs asincrónicos se iniciarán a la vez.

Atención

Cuando ejecute la aplicación en modo DEV, la aplicación espera al primer pedido HTTP para arrancar. Además, cuando se ejecuta en el modo DEV, la aplicación se reiniciará automáticamente cuando sea necesario.

Cuando está en modo PROD, la aplicación arrancará sincrónicamente al iniciarse el servidor.

Jobs Programados

Los jobs programados son ejecutados periódicamente por el framework. Puede pedirle a Play que ejecute un job cada cierto intervalo específico de tiempo mediante la anocación @Every.

import play.jobs.*;
 
@Every("1h")
public class Bootstrap extends Job {
    
    public void doJob() {
        List<User> newUsers = User.find("newAccount = true").fetch();
        for(User user : newUsers) {
            Notifier.sayWelcome(user);
        }
    }
    
}

Si la anotación @Every no es suficiente, puede usar la anotación @On para ejecutar los jobs usando una expresión CRON.

import play.jobs.*;
 
/** Ejecutar a las 12pm (mediodía) cada día **/ 
@On("0 0 12 * * ?")
public class Bootstrap extends Job {
    
    public void doJob() {
        Logger.info("Maintenance job ...");
        ...
    }
    
}

Nota

Para interpretar las expresiones CRON, utilizamos el analizador de Quartz library.

No necesitas devolver un resultado. Si lo haces, el resultado se perderá.

Invocando jobs de tareas

También puede invocar un Job en cualquier momento para que ejecute una tarea específica simplemente llamando al método now() de una instancia de un Job. En tal caso, el job se ejecutará inmediatamente de forma no bloqueante.

public static void encodeVideo(Long videoId) {
    new VideoEncoder(videoId).now();
    renderText("Empieza Codificacion");
}

Una llamada al método now() de un Job retorna un valor Promise que puede usarse para recuperar el resultado de la tarea cuando la misma finalice.

Deteniendo la aplicación

Como a veces tienes que ejecutar alguna acción antes de detener la aplicación, Play también incluye una anotación @OnApplicationStop.

import play.jobs.*;
 
@OnApplicationStop
public class Bootstrap extends Job {
 
    public void doJob() {
        Fixture.deleteAll();
    }
}

Próximos pasos

Veamos ahora cómo combinar los Jobs con el poder de la Programación Asincrónica con HTTP.