jueves, 4 de enero de 2018

Usando tareas App engine schedule cloud functions

En google cloud español publicado en 2018 Jan 04 por Guillaume Laforge

Aproveche las capacidades de cron de App Engine para "schedule" de Cloud Functions

Cloud Functions ofrece a los desarrolladores un entorno sin servidores, para permitirles crear y conectar servicios la cloud, una función a la vez. A día de hoy, todavía falta un aspecto: es la capacidad de programar invocaciones de función.

Digamos que desea obtener una función invocada en un intervalo regular: cada hora, se debe ejecutar alguna función de informe para informarle sobre el estado de sus pedidos. ¿Cómo puedes lograr esto? Nuestra solución en este artículo: aprovecharemos las capacidades cron de App Engine para enviar solicitudes a Cloud Functions.

Exponer una función de nube activada por HTTP

En primer lugar, creé un proyecto de Google Cloud con Cloud Functions habilitado, donde implementé una sencilla función de hello world:

exports.helloWorld = function helloWorld(req, res) {
  // Example input: {"message": "Hello!"}
  if (req.body.message === undefined) {
    // This is an error case, as "message" is required.
    console.log("No message received");
    res.status(400).send('No message defined!');
  } else {
    // Everything is okay.
    console.log(req.body.message);
    res.status(200).send('Success: ' + req.body.message);
  }
};
Esta función helloWorld es una función síncrona que responde a los triggers HTTP.

Para invocarlo (con fines de prueba), se pueden emitir llamadas CURL de la siguiente manera:

curl -X POST https://<REGION>-<PROJECT_ID>.cloudfunctions.net/helloWorld \
     -H "Content-Type: application/json" \
     --data '{"message": "Happy New Year!"}'
Y la función responderá con:

Success: Happy New Year!
Ahora veamos cómo aprovechar las colas de tareas y las capacidades cron de App Engine.

Configurar una pequeña aplicación de App Engine con una definición de cron

A los fines de esta demostración, estoy usando App Engine Standard con Java 8 runtime.

Nota: Mi aplicación utiliza el marco web de Gaelyk para App Engine, con el lenguaje de programación Apache Groovy. Pero la elección del marco web o del lenguaje no es crítica en este consejo, y puedes usar cualquier framework o lenguaje web compatible con App Engine. Sin embargo, en mi caso, mi proyecto se ejecuta en App Engine Standard y su reciente Java 8 runtime. Este aspecto es importante, ya que la forma de configurar las capacidades de cron varía según el tiempo de ejecución que elija. En el tiempo de ejecución de Java, las definiciones de cron utilizarán un formato XML (en lugar de YAML para otros tiempos de ejecución como Go).

Necesitamos hacer dos cosas para programar una invocación de función de nube:


  • Primero, creamos un archivo cron.xml en WEB-INF que define una URL local para nuestra aplicación App Engine, que reenviará las solicitudes entrantes a nuestra función. El archivo cron.xml especifica la programación (es decir, cada 10 minutos), así como una política de reintento opcional.
  • Luego, configuramos nuestra aplicación de App Engine para reenviar las solicitudes a la URL de cron.xml a la función.


Aquí está mi archivo cron.xml:

<cronentries>
  <cron>
    <url>/redirect-hello</url>
    <description>Redirect to the helloWorld function</description>
    <schedule>every 10 minutes</schedule>
  </cron>
</cronentries>
Mi función se invocará cada 10 minutos. Pero puede obtener más información sobre las posibles opciones de programación en la documentación.

Ahora, defino una nueva regla de enrutamiento para mi marco de trabajo web preferido para hacer el reenvío. Las definiciones de ruta se configuran en WEB-INF/routes.groovy en el marco de Gaelyk:

all "/call-hello", forward: "/callHello.groovy"
Definimos el path call-hello que llamará al controlador callHello.groovy, que se encuentra en WEB-INF/groovy. Echemos un vistazo a este controlador (también llamado groovlet) y veamos cómo llama a la función de nube:

out <<
    new URL('https://us-central1-fn-gae-cron.cloudfunctions.net/helloWorld')
        .post(payload: request.inputStream.bytes, 
              headers: ['Content-type': 'application/json'])
        .text
El controlador realiza una solicitud POST a nuestra función en la nube, pasando cualquier carga útil que se haya enviado a App Engine (aunque en nuestro caso, las llamadas cron no pasan ninguna carga útil) y devolvemos el resultado de texto de la llamada a función.

Cuando miro los registros de mi función en el registro de Stackdriver, veré cada 10 minutos que se ha llamado a la función, y aparece un mensaje que dice ¡No hay ningún mensaje definido! (Porque mi llamada cron de App Engine no envía ningún mensaje) .)

Más información

Para esta articulo, se inspiro en esta publicación de Valerii Iatsko, que muestra cómo usar App Engine para Python para programar llamadas a Cloud Functions.

Puede obtener más información sobre la configuración cron de App Engine Java en la documentación.

Si también está interesado en Apache Groovy y Gaelyk, puede consultar:
  • La documentación de Apache Groovy
  • La documentación del framework Gaelyk (y en particular todos los buenos accesos directos ofrecidos para simplificar el uso de App Engine)