Como migrar filas push para o Cloud Tasks

Nesta página, descrevemos como migrar o código de fila push do Task Queues para o Cloud Tasks. O Cloud Tasks agora é a maneira preferencial de trabalhar com filas push do App Engine.

Visão geral

Com o Cloud Tasks, é possível acessar o mesmo serviço acessado com a API RPC Task Queues. Assim, você não precisa recriar suas filas e tarefas push atuais. No entanto, é necessário migrar o código que cria ou interage com filas ou tarefas push para usar a API Cloud Tasks.

É possível criar e interagir com filas e tarefas push usando as APIs REST e RPC do Cloud Tasks, a biblioteca de cliente do Cloud Tasks para Java, a ferramenta de linha de comando gcloud e o Console do Google Cloud. Nesta página, fornecemos exemplos usando a ferramenta gcloud e a biblioteca de cliente do Cloud Tasks para Java.

No Cloud Tasks, todas as filas operam como filas push. No restante deste guia e na documentação do Cloud Tasks, o termo fila é equivalente ao termo fila push. Da mesma forma, o termo tarefa é equivalente ao termo tarefa push.

Recursos não disponíveis no Cloud Tasks

Os recursos a seguir não estão disponíveis no Cloud Tasks:

  • Enfileirar tarefas em transações do Datastore
  • Usar a biblioteca de tarefas adiadas em vez de um serviço de worker
  • Trabalhar com tarefas em aplicativos com vários locatários
  • Simular com o servidor de desenvolvimento local
  • adição de tarefas de maneira assíncrona

Preços e cotas

Migrar as filas push para o Cloud Tasks pode afetar os preços e as cotas do seu aplicativo.

Preços

O Cloud Tasks tem seus próprios preços. Assim como no Task Queues, o envio de solicitações para o aplicativo do App Engine com uma tarefa pode gerar custos.

Cotas

As cotas do Cloud Tasks são diferentes das cotas do Task Queues. Assim como no Task Queues, o envio de solicitações para o aplicativo do App Engine a partir do Cloud Tasks pode afetar as cotas de solicitação do App Engine.

Antes de migrar

Nesta seção, discutimos o que você precisa fazer antes de migrar as filas push para o Cloud Tasks.

Como migrar filas pull

Use o guia para migrar filas pull para migrá-las antes de usar este guia para migrar suas filas push. A migração de filas pull após a migração de filas push não é recomendada porque o uso obrigatório do arquivo queue.yaml provavelmente causará um comportamento inesperado com o Cloud Tasks.

Como proteger a configuração da fila

Depois de iniciar o processo de migração para o Cloud Tasks, modificar o arquivo queue.yaml pode causar comportamento inesperado e não é recomendado. Proteja a configuração da fila contra modificações pelo arquivo queue.yaml seguindo estas etapas:

  1. Configure o SDK do Cloud para omitir o arquivo queue.yaml em implantações futuras.

    Adicione o arquivo queue.yaml a um arquivo .gcloudignore. Para verificar se você já tem um arquivo .gcloudignore, execute o seguinte comando no terminal a partir do diretório de nível superior do aplicativo. Esse comando exibirá o nome do arquivo, se ele existir.

    ls -a | grep .gcloudignore

    Saiba mais sobre arquivos .gcloudignore lendo a referência de .gcloudignore.

  2. Restrinja as permissões no arquivo queue.yaml.

    Siga as práticas recomendadas descritas no nosso guia sobre como proteger a configuração da fila.

  3. Saiba mais sobre o Cloud Tasks e o arquivo queue.yaml (opcional).

    Quando você usa a API Cloud Tasks para gerenciar a configuração da fila, a implantação de um arquivo queue.yaml substitui a configuração definida pelo Cloud Tasks, o que pode causar um comportamento inesperado. Leia Como usar o gerenciamento de filas versus queue.yaml para saber mais.

Como ativar a API Cloud Tasks

Para ativar a API Cloud Tasks, clique em Ativar na API Cloud Tasks na biblioteca de APIs. Se houver um botão Gerenciar em vez de Ativar, você já ativou a API Cloud Task para o projeto e não precisa fazer isso novamente.

Como autenticar o aplicativo na API Cloud Tasks

Você precisa autenticar o aplicativo na API Cloud Tasks. Nesta seção, discutimos a autenticação para dois casos de uso diferentes.

Para desenvolver ou testar seu aplicativo localmente, recomendamos usar uma conta de serviço. Veja instruções sobre como configurar uma conta de serviço e conectá-la ao aplicativo em Como receber e fornecer credenciais da conta de serviço manualmente.

Para implantar o aplicativo no App Engine, você não precisa fornecer nenhuma nova autenticação. As Application Default Credentials (ADC, na sigla em inglês) inferem detalhes de autenticação de aplicativos do App Engine.

Como fazer o download do SDK do Cloud

Faça o download e instale o SDK do Cloud para usar a ferramenta gcloud com a API Cloud Tasks, se você não tiver instalado anteriormente. Execute o seguinte comando do seu terminal se você já tiver o SDK do Cloud instalado.

gcloud components update

Como importar a biblioteca de cliente para Java

Siga as etapas abaixo para usar a biblioteca de cliente do Cloud Tasks para Java com seu aplicativo do App Engine:

  1. Especifique a dependência da biblioteca de cliente do Cloud Tasks no arquivo pom.xml:

    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>google-cloud-tasks</artifactId>
      <version>1.3.0</version>
    </dependency>
    
  2. Importe as dependências da biblioteca de cliente do Cloud Tasks nos arquivos responsáveis por criar e enfileirar suas tarefas:

    import com.google.cloud.tasks.v2.AppEngineHttpRequest;
    import com.google.cloud.tasks.v2.CloudTasksClient;
    import com.google.cloud.tasks.v2.HttpMethod;
    import com.google.cloud.tasks.v2.QueueName;
    import com.google.cloud.tasks.v2.Task;
    

Como criar e gerenciar filas

Nesta seção, descrevemos como criar e gerenciar filas usando a API Cloud Tasks.

Com o Cloud Tasks, você não precisa usar um arquivo queue.yaml para criar ou gerenciar filas. Em vez disso, use a API Cloud Tasks. Não é recomendado usar um arquivo queue.yaml e a API Cloud Tasks, mas isso pode ser inevitável na migração do Task Queues para o Cloud Tasks, dependendo do aplicativo. Leia Como usar o gerenciamento de filas versus queue.yaml para saber mais sobre as práticas recomendadas.

Como criar filas

Leia esta seção se o aplicativo criar filas de maneira programática ou se você quiser criar filas adicionais a partir da linha de comando.

No Cloud Tasks, os nomes de fila têm o formato projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID. A parte LOCATION_ID do nome da fila corresponde a uma região do Google Cloud. A parte QUEUE_ID do nome da fila é equivalente ao campo name da fila no Task Queues. O nome da fila é gerado durante a criação da fila com base no projeto, na região e no QUEUE_ID que você especificar.

Em geral, o local da fila (ou seja, a região) precisa ser o mesmo da região do aplicativo. As duas exceções a essa regra são aplicativos que usam a região europe-west e aplicativos que usam a região us-central. No Cloud Tasks, essas regiões são chamadas de europe-west1 e us-central1, respectivamente.

É possível especificar a configuração de fila opcional durante a criação da fila, mas você também pode fazer isso atualizando a fila depois de criá-la.

Você não precisa recriar filas atuais. Em vez disso, migre o código que interage com as filas atuais lendo as partes relevantes deste guia.

Como reutilizar nomes de fila

Aguarde sete dias após a exclusão de uma fila para criar uma com o mesmo ID de fila no mesmo projeto e local (ou seja, região).

O exemplo a seguir cria duas filas usando o Cloud Tasks. A primeira fila tem o ID queue-blue e está configurada para enviar todas as tarefas para a versão v2 do serviço task-module a uma taxa de 5/s. A segunda fila tem o ID queue-red e envia tarefas a uma taxa de 1/s. Ambos são criados no projeto com o ID do projeto your-project-id no local us-central1. Esse é o equivalente do Cloud Tasks à criação de filas no Task Queues.

gcloud

A ferramenta gcloud infere o projeto e o local a partir da configuração da ferramenta gcloud.

gcloud tasks queues create queue-blue \
--max-dispatches-per-second=5 \
--routing-override=service:task-module,version:v2
gcloud tasks queues create queue-red \
--max-dispatches-per-second=1

biblioteca de cliente

import com.google.cloud.tasks.v2.AppEngineRouting;
import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.LocationName;
import com.google.cloud.tasks.v2.Queue;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.RateLimits;

public class CreateQueue {
  public static void createQueue(
      String projectId, String locationId, String queueBlueName, String queueRedName)
      throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String queueBlueName = "queue-blue";
      // String queueRedName = "queue-red";

      LocationName parent = LocationName.of(projectId, locationId);

      Queue queueBlue =
          Queue.newBuilder()
              .setName(QueueName.of(projectId, locationId, queueBlueName).toString())
              .setRateLimits(RateLimits.newBuilder().setMaxDispatchesPerSecond(5.0))
              .setAppEngineRoutingOverride(
                  AppEngineRouting.newBuilder().setVersion("v2").setService("task-module"))
              .build();

      Queue queueRed =
          Queue.newBuilder()
              .setName(QueueName.of(projectId, locationId, queueRedName).toString())
              .setRateLimits(RateLimits.newBuilder().setMaxDispatchesPerSecond(1.0))
              .build();

      Queue[] queues = new Queue[] {queueBlue, queueRed};
      for (Queue queue : queues) {
        Queue response = client.createQueue(parent, queue);
        System.out.println(response);
      }
    }
  }
}

Saiba mais na referência do Cloud Tasks Como criar uma fila do Cloud Tasks.

Como definir a taxa de processamento da fila

A tabela abaixo lista os campos que diferenciam o Task Queues do Cloud Tasks.

Campo no Task Queues Campo no Cloud Tasks Descrição
rate max_dispatches_per_second A taxa máxima na qual as tarefas são enviadas de uma fila
max_concurrent_requests max_concurrent_dispatches O número máximo de tarefas simultâneas que podem ser enviadas da fila
bucket_size max_burst_size

O Cloud Tasks calcula uma propriedade get-only max_burst_size que limita a velocidade de processamento das tarefas na fila com base no valor de max_dispatches_per_second. O campo permite que a fila tenha uma taxa alta. Dessa maneira, o processamento começará logo depois que uma tarefa for colocada na fila, mas ainda limitará o uso de recursos quando muitas tarefas forem enfileiradas em um curto período.

Para filas do App Engine que foram criadas ou atualizadas usando um arquivo queue.xml/yaml, max_burst_size é inicialmente igual a bucket_size. No entanto, se a fila for transmitida posteriormente para um comando update usando qualquer interface do Cloud Tasks, max_burst_size será redefinido com base no valor de max_dispatches_per_second, independentemente de max_dispatches_per_second ser atualizado.

total_storage_limit Obsoleto no Cloud Tasks No momento, o Cloud Tasks não é compatível com a configuração de um limite de armazenamento personalizado

É possível definir a taxa de processamento da fila ao criá-la ou atualizá-la depois. O exemplo abaixo usa o Cloud Tasks para definir a taxa de processamento de uma fila chamada queue-blue já criada. Se queue-blue tiver sido criado ou configurado usando um arquivo queue.yaml, o exemplo abaixo redefinirá max_burst_size com base no valor max_dispatches_per_second de 20. Esse é o equivalente no Cloud Tasks à definição da taxa de processamento de filas no Task Queues.

gcloud

gcloud tasks queues update queue-blue \
--max-dispatches-per-second=20 \
--max-concurrent-dispatches=10

biblioteca de cliente

import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.LocationName;
import com.google.cloud.tasks.v2.Queue;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.RateLimits;
import com.google.cloud.tasks.v2.UpdateQueueRequest;

public class UpdateQueue {
  public static void updateQueue(String projectId, String locationId, String queueId)
      throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String queueId = "queue-blue";

      LocationName parent = LocationName.of(projectId, locationId);

      Queue queueBlue =
          Queue.newBuilder()
              .setName(QueueName.of(projectId, locationId, queueId).toString())
              .setRateLimits(
                  RateLimits.newBuilder()
                      .setMaxDispatchesPerSecond(20.0)
                      .setMaxConcurrentDispatches(10))
              .build();

      UpdateQueueRequest request = UpdateQueueRequest.newBuilder().setQueue(queueBlue).build();

      Queue response = client.updateQueue(request);
      System.out.println(response);
    }
  }
}

Saiba mais em Definir limites de taxa.

Como desativar e retomar filas

O Cloud Tasks usa o termo pausar da mesma forma que o Task Queues usa o termo desativar. Pausar uma fila interrompe a execução das tarefas até que a fila seja retomada. No entanto, é possível continuar adicionando tarefas a uma fila pausada. O Cloud Tasks usa o termo retomar da mesma forma que o Task Queues.

O exemplo abaixo pausa uma fila com o ID queueName. Esse é o equivalente no Cloud Tasks à desativação de filas no Task Queues.

gcloud

gcloud tasks queues pause queueName

biblioteca de cliente

import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.QueueName;

public class PauseQueue {
  public static void pauseQueue(String projectId, String locationId, String queueId)
      throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String queueId = "foo";

      // Construct the fully qualified queue name.
      String queueName = QueueName.of(projectId, locationId, queueId).toString();

      client.pauseQueue(queueName);
      System.out.println("Queue Paused.");
    }
  }
}

Saiba mais na referência do Cloud Tasks Como pausar filas.

Como excluir filas

Depois de excluir uma fila, aguarde sete dias antes de criar uma fila com o mesmo nome. Considere limpar todas as tarefas de uma fila e reconfigurar a fila, se não puder esperar sete dias.

O exemplo abaixo exclui a fila com o ID foo. Esse é o equivalente no Cloud Tasks à exclusão de filas no Task Queues.

gcloud

gcloud tasks queues delete foo

biblioteca de cliente

import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.QueueName;

public class DeleteQueue {
  public static void deleteQueue(String projectId, String locationId, String queueId)
      throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String queueId = "foo";

      // Construct the fully qualified queue name.
      String queueName = QueueName.of(projectId, locationId, queueId).toString();

      client.deleteQueue(queueName);
      System.out.println("Queue Deleted.");
    }
  }
}

Saiba mais na referência do Cloud Tasks Como excluir filas.

Como criar e gerenciar tarefas

Nesta seção, descrevemos como criar e gerenciar tarefas usando a API Cloud Tasks.

Como criar tarefas

A tabela abaixo lista os campos que diferenciam o Task Queues do Cloud Tasks.

Campo no Task Queues Campo no Cloud Tasks Descrição
NOVO no Cloud Tasks app_engine_http_request Cria uma solicitação que visa um serviço do App Engine. Essas tarefas são chamadas de tarefas do App Engine.
method http_method Especifica o método de solicitação, por exemplo, POST
url relative_uri Especifica o gerenciador de tarefas. Observe a diferença na letra final: i para identificador uniforme de recursos em vez de l para localizador uniforme de recursos
target app_engine_routing Opcional. Especifica service, version e instance do App Engine para uma tarefa do App Engine. Se não for definido, o serviço, a versão e a instância padrão serão usados.

O exemplo a seguir cria uma tarefa que roteia para o gerenciador /worker no serviço padrão do App Engine. Esse é o equivalente do Cloud Tasks à criação de tarefas no Task Queues.

gcloud

gcloud tasks create-app-engine-task --queue=default \
--method=POST --relative-uri=/worker?key=key

biblioteca de cliente

import com.google.cloud.tasks.v2.AppEngineHttpRequest;
import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.HttpMethod;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.Task;
import com.google.protobuf.ByteString;
import java.nio.charset.Charset;

public class CreateTask {
  public static void createTask(String projectId, String locationId, String queueId)
      throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String queueId = "default";
      String key = "key";

      // Construct the fully qualified queue name.
      String queueName = QueueName.of(projectId, locationId, queueId).toString();

      // Construct the task body.
      Task taskParam =
          Task.newBuilder()
              .setAppEngineHttpRequest(
                  AppEngineHttpRequest.newBuilder()
                      .setRelativeUri("/worker?key=" + key)
                      .setHttpMethod(HttpMethod.GET)
                      .build())
              .build();

      Task taskPayload =
          Task.newBuilder()
              .setAppEngineHttpRequest(
                  AppEngineHttpRequest.newBuilder()
                      .setBody(ByteString.copyFrom(key, Charset.defaultCharset()))
                      .setRelativeUri("/worker")
                      .setHttpMethod(HttpMethod.POST)
                      .build())
              .build();

      // Send create task request.
      Task[] tasks = new Task[] {taskParam, taskPayload};
      for (Task task : tasks) {
        Task response = client.createTask(queueName, task);
        System.out.println(response);
      }
    }
  }
}

Saiba mais na referência do Cloud Tasks Como criar tarefas do App Engine.

Como especificar o serviço de destino e o roteamento

A especificação do serviço, da versão e da instância de destino do App Engine para tarefas do App Engine é opcional. Por padrão, as tarefas do App Engine são encaminhadas para o serviço, a versão e a instância que são o padrão no momento em que a tarefa é tentada.

Defina a propriedade app_engine_routing da tarefa durante a criação dela para especificar um serviço, uma versão ou uma instância diferente do App Engine.

Para encaminhar todas as tarefas de uma determinada fila para o mesmo serviço, versão e instância do App Engine, defina a propriedade app_engine_routing_override na fila.

Saiba mais na referência do Cloud Tasks Configurar roteamento.

Como passar dados ao gerenciador

Assim como no Task Queues, é possível transmitir dados para o gerenciador de duas maneiras usando o Cloud Tasks. Você pode transmitir dados como parâmetros de consulta no URI relativo ou transmiti-los no corpo da solicitação usando os métodos HTTP POST ou PUT.

O Cloud Tasks usa o termo corpo da mesma forma que o Task Queues usa o termo payload. No Cloud Tasks, o tipo de conteúdo padrão do corpo é octet-stream, e não texto simples. É possível definir o tipo de conteúdo do body especificando-o no cabeçalho.

O exemplo a seguir transmite uma chave para o gerenciador /worker de duas maneiras diferentes. Esse é o equivalente no Cloud Tasks à transmissão de dados para o gerenciador no Task Queues.

Console

gcloud tasks create-app-engine-task --queue=default --method=GET  \
--relative-uri=/worker?key=blue --routing=service:worker
gcloud tasks create-app-engine-task --queue=default --method=POST \
--relative-uri=/worker --routing=service:worker \
--body-content="{'key': 'blue'}"

biblioteca de cliente

import com.google.cloud.tasks.v2.AppEngineHttpRequest;
import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.HttpMethod;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.Task;
import com.google.protobuf.ByteString;
import java.nio.charset.Charset;

public class CreateTask {
  public static void createTask(String projectId, String locationId, String queueId)
      throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String queueId = "default";
      String key = "key";

      // Construct the fully qualified queue name.
      String queueName = QueueName.of(projectId, locationId, queueId).toString();

      // Construct the task body.
      Task taskParam =
          Task.newBuilder()
              .setAppEngineHttpRequest(
                  AppEngineHttpRequest.newBuilder()
                      .setRelativeUri("/worker?key=" + key)
                      .setHttpMethod(HttpMethod.GET)
                      .build())
              .build();

      Task taskPayload =
          Task.newBuilder()
              .setAppEngineHttpRequest(
                  AppEngineHttpRequest.newBuilder()
                      .setBody(ByteString.copyFrom(key, Charset.defaultCharset()))
                      .setRelativeUri("/worker")
                      .setHttpMethod(HttpMethod.POST)
                      .build())
              .build();

      // Send create task request.
      Task[] tasks = new Task[] {taskParam, taskPayload};
      for (Task task : tasks) {
        Task response = client.createTask(queueName, task);
        System.out.println(response);
      }
    }
  }
}

Como nomear tarefas

A especificação do nome da tarefa é opcional. Se você não especificar o nome da tarefa, o Cloud Tasks criará um para você, gerando um ID da tarefa e inferindo o projeto e o local (isto é, a região) com base na fila especificada durante a criação da tarefa.

Os nomes das tarefas têm o formato projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID. A parte TASK_ID do nome da tarefa é equivalente ao campo name da tarefa no Task Queues.

Como reutilizar nomes de tarefas

Você precisa aguardar antes de reutilizar o nome de uma tarefa. O tempo que você precisa aguardar varia conforme a fila que envia a tarefa foi criada no Cloud Tasks ou no Task Queues.

Para tarefas em filas que foram criadas usando o Task Queues (incluindo a fila padrão), você precisa aguardar cerca de nove dias após a tarefa original ter sido excluída ou executada. Para tarefas em filas que foram criadas usando o Cloud Tasks, você precisa aguardar aproximadamente uma hora após a tarefa original ter sido excluída ou executada.

O exemplo a seguir cria uma tarefa com TASK_ID definido como first-try e o adiciona à fila padrão. Este é o equivalente no Cloud Tasks à nomeação de tarefas no Task Queues.

gcloud

A ferramenta gcloud cria o nome da tarefa inferindo o projeto e o local da configuração.

gcloud tasks create-app-engine-task first-try --queue=default \
--method=GET --relative-uri=/worker

biblioteca de cliente

Com a biblioteca de cliente, você precisa especificar o nome completo da tarefa, se quiser especificar a TASK_ID. O projeto e o local devem corresponder ao projeto e ao local da fila à qual a tarefa foi adicionada.

import com.google.cloud.tasks.v2.AppEngineHttpRequest;
import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.HttpMethod;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.Task;
import com.google.cloud.tasks.v2.TaskName;

public class CreateTaskWithName {
  public static void createTaskWithName(
      String projectId, String locationId, String queueId, String taskId) throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String queueId = "default";
      // String taskId = "first-try"

      String queueName = QueueName.of(projectId, locationId, queueId).toString();

      Task.Builder taskBuilder =
          Task.newBuilder()
              .setName(TaskName.of(projectId, locationId, queueId, taskId).toString())
              .setAppEngineHttpRequest(
                  AppEngineHttpRequest.newBuilder()
                      .setRelativeUri("/worker")
                      .setHttpMethod(HttpMethod.GET)
                      .build());

      // Send create task request.
      Task response = client.createTask(queueName, taskBuilder.build());
      System.out.println(response);
    }
  }
}

Como executar novamente tarefas com falha

É possível definir a configuração de repetição de tarefas em filas durante a criação ou atualizando a fila. A tabela abaixo lista o campo no Task Queues e o campo correspondente no Cloud Tasks.

Campo no Task Queues Campo no Cloud Tasks
task_retry_limit max_attempts
task_age_limit max_retry_duration
min_backoff_seconds min_backoff
max_backoff_seconds max_backoff
max_doublings max_doublings

Parâmetros de repetição específicos da tarefa

Os parâmetros de repetição específicos da tarefa configurados no Task Queues funcionam no Cloud Tasks. No entanto, não é possível editá-los ou defini-los em novas tarefas. Para alterar os parâmetros de repetição de uma tarefa que tenha parâmetros de repetição específicos, recrie a tarefa com uma fila do Cloud Tasks que tenha os parâmetros de repetição desejados.

O exemplo a seguir demonstra vários cenários de novas tentativas:

  • Em fooqueue, as tarefas são repetidas até sete vezes e por até dois dias a partir da primeira tentativa de execução. Depois que ambos os limites são atingidos, elas falham permanentemente.
  • Em barqueue, o Google App Engine tenta repetir tarefas, aumentando o intervalo linearmente entre cada nova tentativa até atingir a espera máxima e repetindo indefinidamente no intervalo máximo. Assim, os intervalos entre solicitações são de 10s, 20s, 30s, ..., 190s, 200s, 200s e assim por diante.
  • Em bazqueue, o intervalo de repetição começa em 10s, depois duplica três vezes, aumenta linearmente e, finalmente, repete indefinidamente no intervalo máximo. Dessa forma, os intervalos entre solicitações são: 10s, 20s, 40s, 80s, 160s, 240s, 300s, 300s ...

Este é o equivalente do Cloud Tasks à repetição de tarefas no Task Queues.

gcloud

Ao definir opções que especifiquem um número de segundos, você precisa incluir s após o número inteiro (por exemplo, 200s, e não 200).

gcloud tasks queues create fooqueue \
--max-attempts=7 \
--max-retry-duration=172800s  #2*60*60*24 seconds in 2 days
gcloud tasks queues create barqueue \
--min-backoff=10s \
--max-backoff=200s \
--max-doublings=0
gcloud tasks queues create bazqueue \
--min-backoff=10s \
--max-backoff=300s \
--max-doublings=3

biblioteca de cliente

import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.LocationName;
import com.google.cloud.tasks.v2.Queue;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.RateLimits;
import com.google.cloud.tasks.v2.RetryConfig;
import com.google.protobuf.Duration;

public class RetryTask {
  public static void retryTask(
      String projectId, String locationId, String fooqueue, String barqueue, String bazqueue)
      throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String fooqueue = "fooqueue";
      // String barqueue = "barqueue";
      // String bazqueue = "bazqueue";

      LocationName parent = LocationName.of(projectId, locationId);

      Duration retryDuration = Duration.newBuilder().setSeconds(2 * 60 * 60 * 24).build();
      Duration min = Duration.newBuilder().setSeconds(10).build();
      Duration max1 = Duration.newBuilder().setSeconds(200).build();
      Duration max2 = Duration.newBuilder().setSeconds(300).build();

      Queue foo =
          Queue.newBuilder()
              .setName(QueueName.of(projectId, locationId, fooqueue).toString())
              .setRateLimits(RateLimits.newBuilder().setMaxDispatchesPerSecond(1.0))
              .setRetryConfig(
                  RetryConfig.newBuilder().setMaxAttempts(7).setMaxRetryDuration(retryDuration))
              .build();

      Queue bar =
          Queue.newBuilder()
              .setName(QueueName.of(projectId, locationId, barqueue).toString())
              .setRateLimits(RateLimits.newBuilder().setMaxDispatchesPerSecond(1.0))
              .setRetryConfig(
                  RetryConfig.newBuilder()
                      .setMinBackoff(min)
                      .setMaxBackoff(max1)
                      .setMaxDoublings(0))
              .build();

      Queue baz =
          Queue.newBuilder()
              .setName(QueueName.of(projectId, locationId, bazqueue).toString())
              .setRateLimits(RateLimits.newBuilder().setMaxDispatchesPerSecond(1.0))
              .setRetryConfig(
                  RetryConfig.newBuilder()
                      .setMinBackoff(min)
                      .setMaxBackoff(max2)
                      .setMaxDoublings(3))
              .build();

      Queue[] queues = new Queue[] {foo, bar, baz};
      for (Queue queue : queues) {
        Queue response = client.createQueue(parent, queue);
        System.out.println(response);
      }
    }
  }
}

Saiba mais na referência do Cloud Tasks Definir parâmetros de repetição.

Como excluir tarefas de uma fila

Ao excluir uma tarefa, aguarde nove dias antes de criá-la com o mesmo nome se ela estava em uma fila criada usando um arquivo queue.yaml ou uma hora, se ela estava em uma fila criada usando o Cloud Tasks.

O exemplo a seguir exclui a tarefa com o ID de tarefa foo da fila com o ID de fila queue1. Esse é o equivalente no Cloud Tasks à exclusão de tarefas no Task Queues.

gcloud

O projeto e o local da tarefa são inferidos do projeto padrão do SDK do Cloud.

gcloud tasks delete foo --queue=queue1

biblioteca de cliente

import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.TaskName;

public class DeleteTask {
  public static void deleteTask(String projectId, String locationId, String queueId, String taskId)
      throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String queueId = "queue1";
      // String taskId = "foo";

      // Construct the fully qualified queue name.
      String taskName = TaskName.of(projectId, locationId, queueId, taskId).toString();

      client.deleteTask(taskName);
      System.out.println("Task Deleted.");
    }
  }
}

Saiba mais na referência do Cloud Tasks Como excluir uma tarefa de uma fila.

Como limpar tarefas

O exemplo a seguir limpa todas as tarefas da fila com o ID da fila foo. Este é o equivalente no Cloud Tasks à limpeza de tarefas no Task Queues.

gcloud

O projeto e o local da fila são inferidos do projeto padrão do SDK do Cloud.

gcloud tasks queues purge foo

biblioteca de cliente

import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.QueueName;

public class PurgeQueue {
  public static void purgeQueue(String projectId, String locationId, String queueId)
      throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String queueId = "foo";

      // Construct the fully qualified queue name.
      String queueName = QueueName.of(projectId, locationId, queueId).toString();

      client.purgeQueue(queueName);
      System.out.println("Queue Purged.");
    }
  }
}

Saiba mais na referência do Cloud Tasks Como limpar todas as tarefas de uma fila.

Um exemplo de Java 8 do Cloud Tasks

O exemplo a seguir é uma configuração básica para criar uma fila e enfileirar uma tarefa para ela com o Cloud Tasks. Ele pressupõe que o desenvolvedor criou um arquivo pom.xml para especificar a dependência do Cloud Tasks, conforme descrito na seção Como importar a biblioteca de cliente. Esse é o equivalente do Cloud Tasks a um exemplo de fila de tarefas do Java 8 no Task Queues.

O arquivo que é responsável por criar e enfileirar a tarefa cria uma tarefa e a adiciona à fila padrão usando a biblioteca de cliente do Cloud Tasks para Java:

import com.google.cloud.tasks.v2.AppEngineHttpRequest;
import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.HttpMethod;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.Task;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(
    name = "TaskEnqueue",
    description = "Enqueue a task targeted at endpoint '/cloudtasks/worker'",
    urlPatterns = "/cloudtasks/enqueue")
public class Enqueue extends HttpServlet {

  // TODO(developer): Replace these variables before running the sample.
  static final String projectId = "my-project-id";
  static final String locationId = "us-central1";

  // Function creates Cloud Tasks from form submissions.
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    String key = request.getParameter("key");

    try (CloudTasksClient client = CloudTasksClient.create()) {
      // Construct the fully qualified queue name.
      String queueName = QueueName.of(projectId, locationId, "default").toString();

      // Construct the task body.
      Task task =
          Task.newBuilder()
              .setAppEngineHttpRequest(
                  AppEngineHttpRequest.newBuilder()
                      .setRelativeUri("/cloudtasks/worker?key=" + key)
                      .setHttpMethod(HttpMethod.POST)
                      .build())
              .build();

      // Add the task to the default queue.
      Task taskResponse = client.createTask(queueName, task);
      System.out.println("Task created: " + taskResponse.getName());
    }

    response.sendRedirect("/");
  }
}

O arquivo que define o worker cuida da tarefa:

import java.io.IOException;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(
    name = "TaskWorker",
    description = "Endpoint to process Cloud Task requests",
    urlPatterns = "/cloudtasks/worker"
)
public class Worker extends HttpServlet {

  private static final Logger log = Logger.getLogger(Worker.class.getName());

  // Worker function to process POST requests from Cloud Tasks targeted at the
  // '/cloudtasks/worker' endpoint.
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    String key = request.getParameter("key");
    log.info("Worker is processing " + key);
  }
}

A seguir