Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Funções de enfileiramento com o Cloud Tasks

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

As funções de fila de tarefas aproveitam o Google Cloud Tasks para ajudar seu aplicativo a executar tarefas demoradas, com uso intensivo de recursos ou com limitação de largura de banda de forma assíncrona, fora do fluxo principal do aplicativo.

Por exemplo, imagine que você deseja criar backups de um grande conjunto de arquivos de imagem atualmente hospedados em uma API com um limite de taxa. Para ser um consumidor responsável dessa API, você precisa respeitar seus limites de taxa. Além disso, esse tipo de tarefa de execução longa pode ser vulnerável a falhas devido a tempos limite e limites de memória.

Para atenuar essa complexidade, você pode escrever uma função de fila de tarefas que defina opções básicas de tarefas como scheduleTime e dispatchDeadline e, em seguida, passar a função para uma fila no Cloud Tasks. O ambiente do Cloud Tasks foi projetado especificamente para garantir o controle de congestionamento eficaz e políticas de repetição para esses tipos de operações.

O Firebase SDK para Cloud Functions para Firebase v3.20.1 e superior interopera com o Firebase Admin SDK v10.2.0 e superior para oferecer suporte a funções de fila de tarefas.

O uso de funções de fila de tarefas com o Firebase pode resultar em cobranças pelo processamento do Cloud Tasks. Consulte os preços do Cloud Tasks para obter mais informações.

Criando funções de fila de tarefas

Para usar funções de fila de tarefas, siga este fluxo de trabalho:

  1. Escreva uma função de fila de tarefas usando o SDK do Firebase para Cloud Functions.
  2. Teste suas funções usando o Firebase Local Emulator Suite.
  3. Implante sua função com a Firebase CLI. Ao implantar sua função de fila de tarefas pela primeira vez, a CLI criará uma fila de tarefas no Cloud Tasks com opções (limitação de taxa e repetição) especificadas em seu código-fonte.
  4. Adicione tarefas à fila de tarefas recém-criada, transmitindo parâmetros para configurar um cronograma de execução, se necessário. Você pode fazer isso escrevendo o código usando o Admin SDK e implantando-o no Cloud Functions para Firebase.

Escrevendo funções de fila de tarefas

Use onTaskDispatched para começar a escrever funções de fila de tarefas. Uma parte importante da gravação de uma função de fila de tarefas é definir a repetição por fila e a configuração de limitação de taxa. Os exemplos de código nesta página são baseados em um aplicativo que configura um serviço que faz backup de todas as imagens da Astronomy Picture of the Day da NASA :

Configuração da fila de tarefas

As funções da fila de tarefas vêm com um poderoso conjunto de definições de configuração para controlar com precisão os limites de taxa e o comportamento de repetição de uma fila de tarefas:

exports.backupapod = onTaskDispatched(
    {
      retryConfig: {
        maxAttempts: 5,
        minBackoffSeconds: 60,
      },
      rateLimits: {
        maxConcurrentDispatches: 6,
      },
    }, async (req) => {
  • retryConfig.maxAttempts=5 : Cada tarefa na fila de tarefas é repetida automaticamente até 5 vezes. Isso ajuda a atenuar erros transitórios, como erros de rede ou interrupção temporária do serviço de um serviço externo dependente.
  • retryConfig.minBackoffSeconds=60 : Cada tarefa é repetida com pelo menos 60 segundos de intervalo entre cada tentativa. Isso fornece um grande buffer entre cada tentativa, para que não tenhamos pressa em esgotar as 5 tentativas de repetição muito rapidamente.
  • rateLimits.maxConcurrentDispatch=6 : No máximo 6 tarefas são despachadas em um determinado momento. Isso ajuda a garantir um fluxo constante de solicitações para a função subjacente e ajuda a reduzir o número de instâncias ativas e inicializações a frio.

Testando as funções da fila de tarefas usando o Firebase Local Emulator Suite

As funções da fila de tarefas no Firebase Local Emulator Suite são expostas como funções HTTP simples. Você pode testar uma função de tarefa emulada enviando uma solicitação HTTP POST com uma carga útil de dados json:

 # start the Local Emulator Suite
 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

Implantando a função de fila de tarefas

Implante a função de fila de tarefas usando o Firebase CLI:

$ firebase deploy --only functions:backupapod

Ao implantar uma função de fila de tarefas pela primeira vez, a CLI cria uma fila de tarefas no Cloud Tasks com opções (limitação de taxa e repetição) especificadas em seu código-fonte.

Se você encontrar erros de permissão ao implantar funções, certifique-se de que as funções apropriadas do IAM sejam atribuídas ao usuário que executa os comandos de implantação.

Enfileirar a função

As funções da fila de tarefas podem ser enfileiradas no Cloud Tasks a partir de um ambiente de servidor confiável, como o Cloud Functions para Firebase, usando o Firebase Admin SDK para Node.js. Se você é novo nos Admin SDKs, consulte Adicionar Firebase a um servidor para começar.

Em um fluxo típico, o Admin SDK cria uma nova tarefa, enfileira-a no Cloud Tasks e define a configuração da tarefa:

exports.enqueuebackuptasks = onRequest(
    async (_request, response) => {
      const queue = getFunctions().taskQueue("backupapod");
      const targetUri = await getFunctionUrl("backupapod");

      const enqueues = [];
      for (let i = 0; i <= BACKUP_COUNT; i += 1) {
        const iteration = Math.floor(i / HOURLY_BATCH_SIZE);
        // Delay each batch by N * hour
        const scheduleDelaySeconds = iteration * (60 * 60);

        const backupDate = new Date(BACKUP_START_DATE);
        backupDate.setDate(BACKUP_START_DATE.getDate() + i);
        // Extract just the date portion (YYYY-MM-DD) as string.
        const date = backupDate.toISOString().substring(0, 10);
        enqueues.push(
            queue.enqueue({date}, {
              scheduleDelaySeconds,
              dispatchDeadlineSeconds: 60 * 5, // 5 minutes
              uri: targetUri,
            }),
        );
      }
      await Promise.all(enqueues);
      response.sendStatus(200);
    });
  • scheduleDelaySeconds : o código de amostra tenta espalhar a execução de tarefas associando um atraso de N-ésimos minutos para a N-ésima tarefa. Isso se traduz em disparar ~ 1 tarefa/minuto. Observe que você também pode usar scheduleTime se quiser que o Cloud Tasks acione uma tarefa em um horário específico.
  • dispatchDeadlineSeconds : quantidade máxima de tempo que o Cloud Tasks aguardará a conclusão de uma tarefa. O Cloud Tasks tentará novamente a tarefa após a configuração de repetição da fila ou até que esse prazo seja atingido. Na amostra, a fila está configurada para repetir a tarefa até 5 vezes, mas a tarefa é cancelada automaticamente se todo o processo (incluindo tentativas de repetição) demorar mais de 5 minutos.

Recupere e inclua o URI de destino

Como o Cloud Functions para Firebase (segunda geração) não oferece suporte a URLs HTTP determinísticos, você deve recuperar e incluir manualmente o URI de destino em cada tarefa enfileirada. Você também pode recuperar programaticamente o URL para sua função, conforme demonstrado abaixo:

/**
 * Get the URL of a given v2 cloud function.
 *
 * @param {string} name the function's name
 * @param {string} location the function's location
 * @return {Promise<string>} The URL of the function
 */
async function getFunctionUrl(name, location="us-central1") {
  if (!auth) {
    auth = new GoogleAuth({
      scopes: "https://www.googleapis.com/auth/cloud-platform",
    });
  }
  const projectId = await auth.getProjectId();
  const url = "https://cloudfunctions.googleapis.com/v2beta/" +
    `projects/${projectId}/locations/${location}/functions/${name}`;

  const client = await auth.getClient();
  const res = await client.request({url});
  const uri = res.data?.serviceConfig?.uri;
  if (!uri) {
    throw new Error(`Unable to retreive uri for function at ${url}`);
  }
  return uri;
}

Solução de problemas

Ativar geração de registros do Cloud Tasks

Os logs do Cloud Tasks contêm informações de diagnóstico úteis, como o status da solicitação associada a uma tarefa. Por padrão, os logs do Cloud Tasks são desativados devido ao grande volume de logs que ele pode gerar em seu projeto. Recomendamos que você ative os logs de depuração enquanto estiver desenvolvendo e depurando ativamente suas funções de fila de tarefas. Consulte Ativando a criação de log .

Permissões IAM

Você pode ver erros PERMISSION PERMISSION DENIED ao enfileirar tarefas ou quando o Cloud Tasks tentar invocar suas funções de fila de tarefas. Certifique-se de que seu projeto tenha as seguintes vinculações do IAM:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
  --role=roles/cloudtasks.enqueuer
  • A identidade usada para enfileirar tarefas no Cloud Tasks precisa de permissão para usar a conta de serviço associada a uma tarefa no Cloud Tasks.

    No exemplo, esta é a conta de serviço padrão do App Engine .

Consulte a documentação do Google Cloud IAM para obter instruções sobre como adicionar a conta de serviço padrão do App Engine como um usuário da conta de serviço padrão do App Engine.

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