hefestoapicontainer

Encolamiento de tareas: jobs y workers

Hefesto incluye dos workers (aunque se pueden levantar más), que permiten ejecutar tareas en segundo plano, de forma que podrás delegar en los workers procesos pesados, procesos que quieras que se ejecuten un tiempo después, etc.

Api hefesto-jobs

Antes de nada, clona y despliega la api hefesto-jobs, que dota a tu virtual-host de varias funcionalidades que se explican a continuación para gestionar tus workers.

Encolar una tarea

Pongamos que tienes el siguiente endpoint:

    post /user:
        LoadUser:
            directive: LoadAndValidateModel
            source: $.message.bodyAsArray
            target: user
        Connect:
            directive: DatabaseConnect
        SaveUser:
            directive: SaveUser
            user: $.memory.user

Se trata de un POST que realiza una validación y almacena un usuario en base de datos.

Si SaveUser fuera una tarea muy pesada, que tarda mucho tiempo, o no quisieramos que se ejecutara en el hilo http por cualquier motivo, podríamos hacer que la parte de base de datos, la ejecutara un worker, cuando estuviera disponible, para ello usaremos la directiva ForTheWorker de esta manera:

    post /user:
        LoadUser:
            directive: LoadAndValidateModel
            source: $.message.bodyAsArray
            target: user
        ForTheWorker:
            directive: ForTheWorker
            identifier: true
            delay: 60
        Connect:
            directive: DatabaseConnect
        SaveUser:
            directive: SaveUser
            user: $.memory.user

ForTheWorker interrumpe el flujo del endpoint, de forma que todas las directivas que haya después de ForTheWorker, no serán ejecutadas en el hilo http, sino que serán encoladas en redis, y procesadas por un worker cuando alguno de ellos esté disponible. Todo el estado del endpoint será mantenido desde el hilo http, a la ejecución en el worker, por lo que cualquier cosa que hayas almacenado en memory, cambios en message, etc, permanecerá.

El parámetro delay es opcional, por defecto es 0, son los segundos que hay que retrasar la ejecución de la tarea, identifier también es opcional, si lo utilizamos, el endpoint devolverá un identificador del worker, que podrá ser utilizado para acceder al estado de la tarea como se explica en la siguiente sección.

Acceder al estado de una tarea

La directiva WriteToJob te permite almacenar mensajes que se pueden leer conociendo el identificador del worker.

Para ello, desde una directiva puedes hacer:

    WriteToJob::run($state,[
        'value' => [
            'message' => 'Lorem Ipsum is simply dummy text'
        ]
    ]);

value puede contener cualquier array, todo el array podrá ser leido usando el siguiente endpoint:

    curl --location --request GET 'https://youradminhost.com/jobs/status/63af17c8c608.048691' \
        --header 'public-host: yourpublichost.com' \
        --header 'public-host-key: your-key'

Siendo 63af17c8c608.048691, el identificador, los dominios y claves los explicados en virtual-host, y la api jobs, hefesto-jobs, la que se pide desplegar en la primera sección.

Conocer el estado de los workers

Haciendo la siguiente llamada:

    curl --location --request GET 'https://youradminhost.com/jobs/count' \
        --header 'public-host: yourpublichost.com' \
        --header 'public-host-key: your-key'

Siendo los dominios y claves los explicados en virtual-host, y la api jobs, hefesto-jobs, la que se pide desplegar en la primera sección.

Recibirás una respuesta como esta:

    {
        "requests": 57721,
        "waiting": 14,
        "processing": 4,
        "failed": 1,
        "success": 57702
    }

Las requests, son el total de tareas que se han encolado, se hayan procesado ya o no, waiting son aquellas que están esperando a ser procesadas por algún worker, processing, son las que se están procesando en este momento, failed las que se procesaron y fallaron (el status del message al terminar de ejecutarse todas las directivas fue 5xx) y success, las que se ejecutaron y terminaron correctamente, es decir su status fue 2xx o 4xx.

Reintentar los workers fallidos

Haciendo la siguiente llamada:

    curl --location --request POST 'https://youradminhost.com/jobs/requeue/failed' \
        --header 'public-host: yourpublichost.com' \
        --header 'public-host-key: your-key'

Siendo los dominios y claves los explicados en virtual-host, y la api jobs, hefesto-jobs, la que se pide desplegar en la primera sección.

Provocarás que todos los jobs que haya en failed, pasen a estar de nuevo en waiting, y se procesen de nuevo.

Eliminar los workers fallidos y los contadores principales

Haciendo la siguiente llamada:

    curl --location --request POST 'https://youradminhost.com/jobs/flush' \
        --header 'public-host: yourpublichost.com' \
        --header 'public-host-key: your-key'

Siendo los dominios y claves los explicados en virtual-host, y la api jobs, hefesto-jobs, la que se pide desplegar en la primera sección.

Provocarás que todos los jobs en failed sean eliminados, pasando este contador a 0, y que los contadores requests y success pasen también a 0.

Aumentar el número de workers

Por defecto, se ejecutan dos workers, si quieres modificar el número de workers, edita laradock/php-worker/supervisord.d/laravel-worker.conf, colocando en numprocs el número de workers que quieres que existan. Si no has realizado aún la instalación, el docker que ejecuta los workers se levantará con ese número de workers, si ya has realizado la instalación:

Ir a la home