Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

¿Buscas un emulador para Cloud Tasks?

By Joshua FoxAug 10, 20205 min read

Esta página también está disponible en English, Deutsch, Français, Italiano, 日本語 y Português.

Te presentamos un emulador de Tasks sencillo que facilita el despliegue y la depuración.

Cuando desarrollas una aplicación que usa Cloud Tasks (digamos, una app web), necesitas ver qué pasa con tus Tasks: cómo se programan, se entregan y las procesa un task handler. Sin embargo, aunque se ha solicitado en numerosas ocasiones, Google no ofrece un emulador para desarrollar con Cloud Tasks comparable al que ofrece para Datastore o PubSub.

Mi nuevo Cloud Tasks In-Process Emulator en Python responde a esa necesidad. Si tienes prisa y quieres usarlo ya mismo, salta directamente al "Quick Start" más abajo.

Formas de desarrollar para Cloud Tasks

Tienes cuatro opciones:

  1. Usar el servicio real de Cloud Tasks.
  2. Usar un emulador en localhost que exponga la misma interfaz HTTP que Cloud Tasks.
  3. Saltártelo sin más: no te preocupes por procesar las tasks. Puedes dejar que la creación de la task falle en silencio, o disparar tasks sin un handler definido.
  4. Usar un emulador in-process. Inyéctalo para usarlo en desarrollo, mientras que en los sistemas desplegados se usa una implementación basada en Cloud Tasks.

Mi recomendación:

  • Un emulador in-process para desarrollo
  • Cloud Tasks real para pruebas de integración en la nube
  • Omitir Cloud Tasks en las pruebas unitarias.

Veamos por qué.

Las ventajas de in-process

Depuración

En desarrollo, quieres saber dónde está cada task y qué contiene. Cuando tu emulador corre in-process, puedes hacerlo desde tu debugger, pausando la cola e inspeccionando los valores.

Lo simple es bueno

El código de este emulador se mantiene muy simple y solo admite la creación y el manejo de tasks. Es algo intencional: una base de código más sencilla (aquí, menos de 100 líneas) resulta mejor cuando estás depurando.

Además, con un producto en alpha —y todos los emuladores de Cloud Tasks, incluido este, están en alpha— quieres la tranquilidad de mantener todo el código bajo tu control directo, para poder depurarlo e incluso editarlo rápidamente.

Para una funcionalidad más completa y pruebas más realistas, yo usaría el Cloud Tasks real, en una aplicación desplegada en la nube.

Facilidad de uso

Otros emuladores de Cloud Tasks, como gcloud-tasks-emulator de Potato London y cloud-tasks-emulator de Aert van de Hulsbeek, corren en localhost y tienen la ventaja de exponer la misma API que el servicio en la nube; solo necesitas cambiar el endpoint. Además, código en cualquier lenguaje puede llamar a estos emuladores; algo que no es posible con el emulador in-process.

Por otro lado, suponen la carga adicional de otro proceso: hay que lanzarlo antes de cada sesión de desarrollo y estar pendiente de si se cayó o se congeló. Y aunque puedes depurarlos si los lanzas dentro de un debugger, lo más probable es que eso no forme parte de tu flujo principal de desarrollo.

No pierdas tus Tasks

Tienes la opción de disparar tasks hacia Cloud Tasks y no procesarlas nunca; o simplemente dejar que su creación falle en silencio. Esto funciona bien si tu flujo principal de desarrollo no implica procesar las tasks: por ejemplo, si las maneja un microservicio aparte del que se encarga otro equipo. También funciona bien para pruebas unitarias, ya que estas generalmente no se usan para probar procesos asíncronos distribuidos; ese es el papel de las pruebas de integración.

Pero si quieres ver qué ocurre realmente con tus tasks, y cómo el callback las procesa, necesitas algún tipo de emulador.

Desarrolla con la nube, o sin ella

Para un flujo end-to-end completo, también puedes usar el Cloud Tasks real desde tu máquina de desarrollo, con la misma API y funcionalidad que en el sistema desplegado. Esto funciona bien para pruebas de integración que se ejecutan en la nube.

Sin embargo, si lo intentas en tu máquina de desarrollo, vas a necesitar siempre una conexión a internet; y vas a tener que configurar un proxy como ngrok para que Google Cloud Platform pueda llegar a tu máquina local (como se describe aquí). Usar la API real de Cloud Tasks también requiere colas reales, lo que significa que o bien necesitas tu propio proyecto de Google Cloud, o tienes que gestionar las colas de modo que cada desarrollador tenga su propio conjunto.

También implica que depurar incluso un proceso simple en tu máquina de desarrollo te obliga a recurrir a la Cloud Console para obtener más información. En mi caso, prefiero ahorrarme la configuración y mantener la depuración dentro de mi proceso.

Funcionalidades y limitaciones

Este proyecto admite la funcionalidad que normalmente usas en desarrollo: crear una task y luego procesarla en un callback.

Sin embargo, por la preferencia por la simplicidad ya mencionada, no admite otras funcionalidades, como:

  • Gestión de colas, incluyendo crear, eliminar, purgar, pausar y reanudar colas. (Al crear una task, la cola se crea automáticamente si aún no existe).
  • Rate-limits y reintentos.
  • Deduplicación y eliminación de tasks.

Si te gustaría ver nuevas funcionalidades (y si son lo bastante simples como para justificar la complejidad añadida), envía Pull Requests o Issues en GitHub.

Quick Start

Para usar este emulador, solo copia emulator.py en tu base de código —incluso puedes hacer copy/paste del código de ese archivo directamente desde GitHub— y listo.

Crea un objeto Emulator y pásale una función callback, que recibirá los payloads de las tasks que crees. Luego, para enviar tasks, llama al método Emulator.create_task. Puedes elegir el nombre de la cola, así como la hora programada de entrega.

Ejemplo de uso

En el proyecto puedes ver emulator.py en acción dentro de una webapp simple. Inícialo ejecutando local_server.py. Luego navega a http://127.0.0.1:8080 (o haz clic en el enlace que verás en la consola) y se creará una task. La task se procesará (se imprimirá en la salida estándar) tres segundos más tarde, según lo programado.

Si eres estricto con la higiene del código y quieres mantener la base de código de producción libre del emulador —omitiendo emulator.py en el despliegue—, este ejemplo te muestra cómo hacerlo. En local_server.py, que se usa en desarrollo, se inyecta un Emulator. En cambio, en un servidor desplegado, donde no se inyecta ningún Emulator, se crea un nuevo CloudTasksAccessor que invoca la API real de Cloud Tasks, manteniendo así el código del servidor (main.py) libre de cualquier código del emulador.