Mettre des fonctions en file d'attente avec Cloud Tasks


Les fonctions de file d'attente de tâches tirent parti de Cloud Tasks de Google pour aider votre application à exécuter des tâches chronophages, gourmandes en ressources ou à bande passante limitée de manière asynchrone, en dehors du flux principal de votre application.

Par exemple, imaginons que vous souhaitiez créer des sauvegardes d'un grand ensemble de fichiers image actuellement hébergés sur une API avec une limite de débit. Pour être un consommateur responsable de cette API, vous devez respecter ses limites de débit. De plus, ce type de job de longue durée peut échouer en raison de délais d'attente et de limites de mémoire.

Pour atténuer cette complexité, vous pouvez écrire une fonction de file d'attente de tâches qui définit des options de tâches de base telles que scheduleTime et dispatchDeadline, puis transmet la fonction à une file d'attente dans Cloud Tasks. L'environnement Cloud Tasks est conçu spécifiquement pour assurer un contrôle efficace de la congestion et des règles de réessai pour ces types d'opérations.

Le SDK Firebase pour Cloud Functions for Firebase version 3.20.1 et ultérieure interagit avec Firebase Admin SDK version 10.2.0 et ultérieure pour prendre en charge les fonctions de file d'attente des tâches.

L'utilisation de fonctions de file d'attente de tâches avec Firebase peut entraîner des frais de traitement Cloud Tasks. Pour en savoir plus, consultez la page sur les tarifs de Cloud Tasks.

Créer des fonctions de file d'attente de tâches

Pour utiliser les fonctions de file d'attente des tâches, suivez ce workflow :

  1. Écrivez une fonction de file d'attente des tâches à l'aide du SDK Firebase pour Cloud Functions.
  2. Testez votre fonction en la déclenchant avec une requête HTTP.
  3. Déployez votre fonction avec la CLI Firebase. Lorsque vous déployez votre fonction de file d'attente des tâches pour la première fois, la CLI crée une file d'attente des tâches dans Cloud Tasks avec les options (limitation du débit et nouvelle tentative) spécifiées dans votre code source.
  4. Ajoutez des tâches à la file d'attente de tâches que vous venez de créer, en transmettant des paramètres pour configurer un calendrier d'exécution si nécessaire. Pour ce faire, écrivez le code à l'aide de Admin SDK et déployez-le sur Cloud Functions for Firebase.

Écrire des fonctions de file d'attente des tâches

Utilisez onDispatch pour commencer à écrire des fonctions de file d'attente des tâches. Une partie importante de l'écriture d'une fonction de file d'attente de tâches consiste à définir la configuration des nouvelles tentatives et de la limitation du débit par file d'attente. Les exemples de code de cette page sont basés sur une application qui configure un service permettant de sauvegarder toutes les images de la page Astronomy Picture of the Day de la NASA :

Configurer les fonctions de file d'attente des tâches

Les fonctions de file d'attente de tâches sont fournies avec un ensemble puissant de paramètres de configuration permettant de contrôler précisément les limites de débit et le comportement de nouvelle tentative d'une file d'attente de tâches :

exports.backupApod = functions
    .runWith( {secrets: ["NASA_API_KEY"]})
    .tasks.taskQueue({
      retryConfig: {
        maxAttempts: 5,
        minBackoffSeconds: 60,
      },
      rateLimits: {
        maxConcurrentDispatches: 6,
      },
    }).onDispatch(async (data) => {
  • retryConfig.maxAttempts=5 : chaque tâche de la file d'attente des tâches fait automatiquement l'objet de cinq tentatives au maximum. Cela permet d'atténuer les erreurs temporaires telles que les erreurs réseau ou les interruptions temporaires de service d'un service externe dépendant.
  • retryConfig.minBackoffSeconds=60 : chaque tâche est relancée au moins 60 secondes après chaque tentative. Cela offre une grande marge entre chaque tentative afin de ne pas épuiser trop rapidement les cinq tentatives.
  • rateLimits.maxConcurrentDispatch=6 : Au maximum six tâches sont distribuées à un moment donné. Cela permet d'assurer un flux constant de requêtes vers la fonction sous-jacente et de réduire le nombre d'instances actives et de démarrages à froid.

Tester les fonctions de file d'attente des tâches

Dans la plupart des cas, l'émulateur Cloud Functions est la meilleure façon de tester les fonctions de file d'attente des tâches. Consultez la documentation d'Emulator Suite pour savoir comment instrumenter votre application pour l'émulation des fonctions de file d'attente des tâches.

De plus, les fonctions de file d'attente des tâches sont exposées en tant que fonctions HTTP simples dans Firebase Local Emulator Suite. Vous pouvez tester une fonction de tâche émulée en envoyant une requête HTTP POST avec une charge utile de données JSON :

 # start the Firebase Emulators
 firebase emulators:start

 # trigger the emulated task queue function
 curl \
  -X POST                                            # An HTTP POST request...
  -H "content-type: application/json" \              # ... with a JSON body
  http://localhost:$PORT/$PROJECT_ID/$REGION/$NAME \ # ... to function url
  -d '{"data": { ... some data .... }}'              # ... with JSON encoded data

Déployer des fonctions de file d'attente de tâches

Déployez la fonction de file d'attente des tâches à l'aide de la CLI Firebase :

$ firebase deploy --only functions:backupApod

Lorsque vous déployez une fonction de file d'attente des tâches pour la première fois, la CLI crée une file d'attente des tâches dans Cloud Tasks avec les options (limitation du débit et nouvelle tentative) spécifiées dans votre code source.

Si vous rencontrez des erreurs d'autorisation lors du déploiement de fonctions, assurez-vous que les rôles IAM appropriés sont attribués à l'utilisateur qui exécute les commandes de déploiement.

Mettre en file d'attente des fonctions de file d'attente de tâches

Les fonctions de file d'attente des tâches peuvent être mises en file d'attente dans Cloud Tasks à partir d'un environnement serveur fiable tel que Cloud Functions for Firebase à l'aide de Firebase Admin SDK pour Node.js. Si vous n'avez jamais utilisé Admin SDK, consultez Ajouter Firebase à un serveur pour commencer.

Dans un flux typique, Admin SDK crée une tâche, la met en file d'attente dans Cloud Tasks et définit la configuration de la tâche :

exports.enqueueBackupTasks = functions.https.onRequest(
async (_request, response) => {
  const queue = getFunctions().taskQueue("backupApod");
  const enqueues = [];
  for (let i = 0; i <= 10; i += 1) {
    // Enqueue each task with i*60 seconds delay. Our task queue function
    // should process ~1 task/min.
    const scheduleDelaySeconds = i * 60 
    enqueues.push(
        queue.enqueue(
          { id: `task-${i}` },
          {
            scheduleDelaySeconds,
            dispatchDeadlineSeconds: 60 * 5 // 5 minutes
          },
        ),
    );
  }
  await Promise.all(enqueues);
  response.sendStatus(200);

});
  • scheduleDelaySeconds : l'exemple de code tente de répartir l'exécution des tâches en associant un délai de N minutes à la N-ième tâche. Cela se traduit par le déclenchement d'environ une tâche par minute. Notez que vous pouvez également utiliser scheduleTime si vous souhaitez que Cloud Tasks déclenche une tâche à une heure spécifique.
  • dispatchDeadlineSeconds : durée maximale pendant laquelle Cloud Tasks attendra la fin d'une tâche. Cloud Tasks tentera de relancer la tâche en suivant la configuration des tentatives de la file d'attente ou jusqu'à ce que ce délai soit atteint. Dans l'exemple, la file d'attente est configurée pour réessayer la tâche jusqu'à cinq fois, mais la tâche est automatiquement annulée si l'ensemble du processus (y compris les tentatives) prend plus de cinq minutes.

Dépannage

Activer la journalisation Cloud Tasks

Les journaux de Cloud Tasks contiennent des informations de diagnostic utiles, comme l'état de la requête associée à une tâche. Par défaut, les journaux de Cloud Tasks sont désactivés en raison du volume important de journaux qu'il peut potentiellement générer dans votre projet. Nous vous recommandons d'activer les journaux de débogage lorsque vous développez et déboguez activement vos fonctions de file d'attente des tâches. Consultez Activer la journalisation.

Autorisations IAM

Des erreurs PERMISSION DENIED peuvent s'afficher lorsque vous mettez des tâches en file d'attente ou lorsque Cloud Tasks tente d'appeler vos fonctions de file d'attente de tâches. Assurez-vous que votre projet dispose des liaisons IAM suivantes :

  • L'identité utilisée pour mettre en file d'attente les tâches sur Cloud Tasks doit disposer de l'autorisation IAM cloudtasks.tasks.create.

    Dans l'exemple, il s'agit du compte de service par défaut App Engine.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
  --role=roles/cloudtasks.enqueuer
  • L'identité utilisée pour mettre en file d'attente des tâches dans Cloud Tasks doit être autorisée à utiliser le compte de service associé à une tâche dans Cloud Tasks.

    Dans l'exemple, il s'agit du compte de service par défaut App Engine.

Consultez la documentation Google Cloud IAM pour savoir comment ajouter le compte de service par défaut App Engine en tant qu'utilisateur du compte de service par défaut App Engine.

  • L'identité utilisée pour déclencher la fonction de file d'attente des tâches doit disposer de l'autorisation cloudfunctions.functions.invoke.

    Dans l'exemple, il s'agit du compte de service par défaut App Engine.

gcloud functions add-iam-policy-binding $FUNCTION_NAME \
  --region=us-central1 \
  --member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
  --role=roles/cloudfunctions.invoker