如何跟踪 Firebase 函数任务队列何时用尽所有重试?

Tin*_*ger 6 firebase google-cloud-functions

我正在使用 Firebase 函数任务队列来调用众多 API 端点。

每个函数都设置为在遇到错误时重试 5 次。

现在我想跟踪函数是否成功完成或完全失败(即所有重试都已用尽并且函数仍然抛出错误)。

我想跟踪这个,以便如果它完全失败我可以更新 Firestore 文档或发送某种类型的警报。

例如,这里有一个任务队列功能,我如何添加上述功能?

export const someTask = functions.tasks
  .taskQueue({
    retryConfig: {
      maxAttempts: 5,
      minBackoffSeconds: 60,
    },
    rateLimits: {
      maxConcurrentDispatches: 1,
    },
  })
  .onDispatch(
    async () => {
      try {
        // Call the API
        await apiCall();
        return;
      } catch (error) {
        // Throw error so that the Task Queue will retry
        throw new functions.https.HttpsError(
          'unknown',
          'someTask error'
        );
      }
    }
  );
Run Code Online (Sandbox Code Playgroud)

Ben*_*ner 4

这不能在本地完成,因为context提供的参数onDispatch仅保存身份验证详细信息:(

所以我们必须在函数之外跟踪它。

此示例会针对每次重试、成功或完全失败更新 Firestore 文档。有一个名为 Firstore 的集合functionStatus,每个文档的 ID 等于您要跟踪的函数的名称。在此示例中,文档 ID 为someTask。这种命名约定使更新状态变得更加容易。

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';

const increment = admin.firestore.FieldValue.increment;

export const someTask = functions.tasks
  .taskQueue({
    retryConfig: {
      maxAttempts: 5,
      minBackoffSeconds: 60,
    },
    rateLimits: {
      maxConcurrentDispatches: 1,
    },
  })
  .onDispatch(async () => {
    try {
      // Call the API
      await apiCall();
    } catch (error) {
      // Get the functionStatus someTask doc
      const someTaskDoc = await admin
        .firestore()
        .collection('functionStatus')
        .doc('someTask')
        .get();

      if (someTaskDoc.data()?.retries < 5) {
        // Update the retry count because we have retries left
        await admin
          .firestore()
          .collection('functionStatus')
          .doc('someTask')
          .update({ retries: increment(1) });
      } else {
        // Update the status to failed because retries are spent
        await admin
          .firestore()
          .collection('functionStatus')
          .doc('someTask')
          .update({ status: 'failed' });
      }

      // Throw the error to start the retry (or if retries are spent kill the function completely)
      throw new functions.https.HttpsError('unknown', 'someTask error');
    }

    // Everything worked. Mark function as successful
    await admin
      .firestore()
      .collection('functionStatus')
      .doc('someTask')
      .update({ status: 'success' });
  });
Run Code Online (Sandbox Code Playgroud)