Migrar filas de envio para o Cloud Tasks (Java)

Esta página descreve como pode migrar o código da fila de envio do Task Queues para o Cloud Tasks. O Cloud Tasks é agora a forma preferencial de trabalhar com filas push do App Engine.

Com o Cloud Tasks, acede ao mesmo serviço ao qual acede com a API RPC de filas de tarefas. Isto significa que não tem de recriar as filas de envio e as tarefas de envio existentes. No entanto, tem de migrar o código que cria ou interage com filas de envio ou tarefas de envio para usar a API Cloud Tasks.

Pode criar e interagir com filas push e tarefas push através das APIs REST e RPC do Cloud Tasks, da biblioteca de cliente do Cloud Tasks, da Google Cloud CLI e da Google Cloud consola. Esta página fornece exemplos que usam a CLI gcloud e a biblioteca cliente do Cloud Tasks.

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

Funcionalidades não disponíveis no Cloud Tasks

As seguintes funcionalidades não estão disponíveis no Cloud Tasks:

  • Colocar tarefas em fila em transações do Datastore
  • Usar a biblioteca de tarefas diferidas em vez de um serviço de trabalho
  • Trabalhar com tarefas em aplicações multi-inquilino
  • Simular com o servidor de desenvolvimento local
  • Adicionar tarefas de forma assíncrona

Preços e quotas

A migração das filas de envio para o Cloud Tasks pode afetar os preços e as quotas da sua app.

Preços

O Cloud Tasks tem a sua própria tabela de preços. Tal como acontece com as filas de tarefas, o envio de pedidos para a sua app do App Engine com uma tarefa pode fazer com que a app incorra em custos.

Quotas

As cotas do Cloud Tasks são diferentes das cotas das filas de tarefas. Tal como acontece com as filas de tarefas, o envio de pedidos para a sua app do App Engine a partir do Cloud Tasks pode afetar as quotas de pedidos do App Engine.

Antes da migração

As secções seguintes abordam os passos de configuração antes de migrar as suas filas de envio para o Cloud Tasks.

Migrar filas de solicitações

Antes de começar, migre as filas de obtenção antes de seguir as instruções neste guia para migrar as filas de envio. Não é recomendado migrar filas de obtenção após a migração de filas de envio, porque a utilização obrigatória do ficheiro queue.yaml vai provavelmente causar um comportamento inesperado com o Cloud Tasks.

Proteção da configuração da fila

Assim que iniciar o processo de migração para o Cloud Tasks, a modificação do ficheiro queue.yaml pode causar um comportamento inesperado e não é recomendada. Proteja a configuração da fila contra modificações através do ficheiro queue.yaml com os seguintes passos.

  1. Configure a CLI gcloud para omitir o ficheiro queue.yaml em implementações futuras.

    Adicione o ficheiro queue.yaml a um ficheiro .gcloudignore. Para verificar se já tem um ficheiro .gcloudignore, pode executar o seguinte comando no terminal a partir do diretório de nível superior da sua app. Este comando apresenta o nome do ficheiro se o ficheiro existir.

    ls -a | grep .gcloudignore

    Para saber mais sobre os ficheiros .gcloudignore, leia a .gcloudignore referência.

  2. Restrinja as autorizações no seu ficheiro queue.yaml.

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

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

    Quando usa a API Cloud Tasks para gerir a configuração da fila, a implementação de um ficheiro queue.yaml substitui a configuração definida pelo Cloud Tasks, o que pode causar um comportamento inesperado. Leia o artigo Usar a gestão de filas em comparação com queue.yaml para saber mais.

Ativar a API Cloud Tasks

Para ativar a API Cloud Tasks, clique em Ativar na API Cloud Tasks na biblioteca de APIs. Se vir um botão Gerir em vez de um botão Ativar, significa que ativou anteriormente a API Cloud Tasks para o seu projeto e não precisa de o fazer novamente.

Autenticar a sua app na Cloud Tasks API

Tem de autenticar a sua app na API Cloud Tasks. Esta secção aborda a autenticação para dois exemplos de utilização diferentes.

Para desenvolver ou testar a sua app localmente, recomendamos que use uma conta de serviço. Para ver instruções sobre como configurar uma conta de serviço e associá-la à sua app, leia o artigo Obter e fornecer credenciais da conta de serviço manualmente.

Para implementar a sua app no App Engine, não precisa de fornecer nenhuma nova autenticação. As Credenciais padrão da aplicação (ADC) deduzem os detalhes de autenticação para apps do App Engine.

Transferir a CLI gcloud

Transfira e instale a CLI gcloud para usar a CLI gcloud com a API Cloud Tasks se não a tiver instalado anteriormente. Execute o seguinte comando a partir do terminal se já tiver a CLI gcloud instalada.

gcloud components update

Importar as bibliotecas de cliente da nuvem

Para usar a biblioteca cliente do Cloud Tasks com a sua app do App Engine:

  1. Especifique a dependência da biblioteca de cliente do Cloud Tasks no ficheiro 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 ficheiros responsáveis pela criação e colocação em fila das 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;

Criar e gerir filas

Esta secção descreve como criar e gerir filas através da API Cloud Tasks.

Com o Cloud Tasks, não usa um ficheiro queue.yaml para criar nem gerir filas. Em alternativa, usa a API Cloud Tasks. Não é recomendável usar um ficheiro queue.yaml e a API Cloud Tasks, mas pode ser uma parte inevitável da migração de filas de tarefas para o Cloud Tasks, consoante a sua app. Leia o artigo Usar a gestão de filas em comparação com queue.yaml para saber mais sobre as práticas recomendadas.

Criar filas

Leia esta secção se a sua app criar filas programaticamente ou se quiser criar filas adicionais a partir da linha de comandos.

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

Em geral, a localização da fila (ou seja, a região) tem de ser a mesma que a região da sua app. As duas exceções a esta regra aplicam-se a apps que usam a região europe-west e apps que usam a região us-central. No Cloud Tasks, estas regiões são denominadas europe-west1 e us-central1, respetivamente.

Pode especificar a configuração opcional da fila durante a criação da fila. No entanto, também pode fazê-lo atualizando a fila após a sua criação.

Não precisa de recriar filas existentes. Em alternativa, migre o código que interage com as suas filas existentes lendo as partes relevantes deste guia.

Reutilizar nomes de filas

Tem de aguardar 7 dias após eliminar uma fila para criar uma fila com o mesmo ID da fila no mesmo projeto e localização (ou seja, região).

O exemplo seguinte cria duas filas através do Cloud Tasks. A primeira fila tem o ID da fila 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 da fila 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 na localização us-central1. Este é o equivalente do Cloud Tasks à criação de filas nas filas de tarefas.

gcloud

A CLI gcloud infere o projeto e a localização a partir da configuração da CLI 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 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);
      }
    }
  }
}

Para saber mais, leia a referência do Cloud Tasks Criar uma fila do Cloud Tasks.

Definir a taxa de processamento da fila

A tabela seguinte indica os campos que diferem entre as filas de tarefas e o Cloud Tasks.

Campo Filas de tarefas Campo do Cloud Tasks Descrição
rate max_dispatches_per_second A taxa máxima à qual as tarefas são enviadas da fila
max_concurrent_requests max_concurrent_dispatches O número máximo de tarefas simultâneas que podem ser enviadas a partir da fila
bucket_size max_burst_size

O Cloud Tasks calcula uma propriedade de obtenção exclusiva max_burst_size que limita a rapidez com que as tarefas na fila são processadas com base no valor de max_dispatches_per_second. Este campo permite que a fila tenha uma taxa elevada para que o processamento comece pouco depois de uma tarefa ser colocada em fila, mas continua a limitar a utilização de recursos quando muitas tarefas são colocadas em fila num curto período de tempo.

Para filas do App Engine criadas ou atualizadas através de um ficheiro queue.xml/yaml, o valor de max_burst_size é inicialmente igual a bucket_size. No entanto, se a fila for posteriormente transmitida a um comando update através de qualquer interface do Cloud Tasks, max_burst_size é reposto com base no valor de max_dispatches_per_second, independentemente de max_dispatches_per_second ser atualizado.

total_storage_limit Descontinuado no Cloud Tasks O Cloud Tasks não suporta a definição de um limite de armazenamento personalizado

Pode definir a taxa de processamento da fila quando a cria ou a atualiza posteriormente. O exemplo seguinte usa o Cloud Tasks para definir a taxa de processamento numa fila denominada queue-blue que já foi criada. Se queue-blue foi criado ou configurado através de um ficheiro queue.yaml, o seguinte exemplo repõe max_burst_size com base no valor max_dispatches_per_second de 20. Isto é o equivalente do Cloud Tasks a definir a taxa de processamento da fila nas filas de tarefas.

gcloud

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

biblioteca 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);
    }
  }
}

Para saber mais, consulte o artigo Defina limites de taxa.

Desativar e retomar filas

O Cloud Tasks usa o termo pausar da mesma forma que as filas de tarefas usam o termo desativar. Pausar uma fila impede a execução das tarefas na fila até que a fila seja retomada. No entanto, pode continuar a adicionar tarefas a uma fila pausada. O Cloud Tasks usa o termo retomar da mesma forma que as filas de tarefas.

O exemplo seguinte pausa uma fila com o ID queueName . Isto é o equivalente do Cloud Tasks a desativar filas nas filas de tarefas.

gcloud

gcloud tasks queues pause 

queueName

biblioteca 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.");
    }
  }
}

Para saber mais, leia a referência do Cloud Tasks sobre como pausar filas.

Eliminar filas

Depois de eliminar uma fila, tem de aguardar 7 dias antes de criar uma fila com o mesmo nome. Considere eliminar todas as tarefas de uma fila e reconfigurar a fila se não puder aguardar 7 dias.

O exemplo seguinte elimina a fila com o ID da fila foo . Esta ação é o equivalente do Cloud Tasks a eliminar filas nas filas de tarefas.

gcloud

gcloud tasks queues delete 

foo

biblioteca 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.");
    }
  }
}

Para saber mais, leia a referência do Cloud Tasks sobre como eliminar filas.

Criar e gerir tarefas

Esta secção descreve como criar e gerir tarefas através da API Cloud Tasks.

Criar tarefas

A tabela seguinte indica os campos que diferem entre as filas de tarefas e o Cloud Tasks.

Campo Filas de tarefas Campo do Cloud Tasks Descrição
NOVO no Cloud Tasks app_engine_http_request Cria um pedido que segmenta um serviço do App Engine. Estas tarefas são denominadas tarefas do App Engine.
method http_method Especifica o método de pedido; por exemplo, POST
url relative_uri Especifica o controlador de tarefas. Tenha em atenção a diferença na última letra: i para identificador de recursos uniforme em vez de l para localizador de recursos uniforme
target app_engine_routing Opcional. Especifica o service do App Engine, version e instance para uma tarefa do App Engine. Se não estiver definido, são usados o serviço, a versão e a instância predefinidos.

O exemplo seguinte cria uma tarefa que é encaminhada para o controlador /worker no serviço do App Engine predefinido. Isto é o equivalente do Cloud Tasks a criar tarefas em filas de tarefas.

gcloud

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

biblioteca 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);
      }
    }
  }
}

Para saber mais, leia a referência do Cloud Tasks Criar tarefas do App Engine.

Especificar o serviço de destino e o encaminhamento

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 predefinição, as tarefas do App Engine são encaminhadas para o serviço, a versão e a instância que são predefinidos no momento em que a tarefa é tentada.

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

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

Para saber mais, leia a referência do Cloud Tasks Configure o encaminhamento.

Transmitir dados ao controlador

Tal como com as filas de tarefas, pode transmitir dados ao controlador de duas formas com o Cloud Tasks. Pode transmitir dados como parâmetros de consulta no URI relativo ou pode transmitir dados no corpo do pedido através dos métodos HTTP POST ou PUT.

O Cloud Tasks usa o termo corpo da mesma forma que as filas de tarefas usam o termo carga útil. No Cloud Tasks, o tipo de conteúdo do corpo predefinido é octet-stream e não texto simples. Pode definir o tipo de conteúdo do corpo especificando-o no cabeçalho.

O exemplo seguinte passa uma chave para o controlador /worker de duas formas diferentes. Esta é a equivalência do Cloud Tasks de transmitir dados ao processador nas filas de tarefas.

consola

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 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);
      }
    }
  }
}

Atribuir nomes às tarefas

A especificação do nome da tarefa é opcional. Se não especificar o nome da tarefa, o Cloud Tasks cria-o por si gerando um ID da tarefa e inferindo o projeto e a localização (ou seja, a região) com base na fila que especificou 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 Task Queues.

Reutilizar nomes de tarefas

Tem de esperar antes de reutilizar o nome de uma tarefa. O tempo que tem de esperar antes de o fazer varia consoante a fila que envia a tarefa foi criada no Cloud Tasks ou nas filas de tarefas.

Para tarefas em filas criadas com filas de tarefas (incluindo a fila predefinida), tem de aguardar aproximadamente 9 dias após a eliminação ou a execução da tarefa original. Para tarefas em filas criadas com o Cloud Tasks, tem de aguardar aproximadamente 1 hora após a tarefa original ter sido eliminada ou executada.

O exemplo seguinte cria uma tarefa com o TASK_ID definido como first-try e adiciona-a à fila predefinida. Isto é o equivalente do Cloud Tasks a atribuir nomes a tarefas nas filas de tarefas.

gcloud

A CLI gcloud cria o nome da tarefa inferindo o projeto e a localização a partir da sua configuração.

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

/worker

biblioteca cliente

Com a biblioteca de cliente, tem de especificar o nome completo da tarefa se quiser especificar o TASK_ID. O projeto e a localização têm de corresponder ao projeto e à localização da fila à qual a tarefa é 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);
    }
  }
}

Repetir tarefas com falha

Pode definir a configuração de novas tentativas de tarefas em filas durante a criação de filas ou atualizando a fila. A tabela seguinte lista o campo Task Queues e o campo Cloud Tasks correspondente.

Campo Filas de tarefas Campo do 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 que foram configurados nas filas de tarefas funcionam no Cloud Tasks. No entanto, não pode editá-los nem defini-los em novas tarefas. Para alterar os parâmetros de repetição de uma tarefa que tem parâmetros de repetição específicos da tarefa, recrie a tarefa com uma fila do Cloud Tasks que tenha os parâmetros de repetição pretendidos.

O exemplo seguinte demonstra vários cenários de repetição:

  • Em fooqueue, as tarefas são repetidas até sete vezes e durante um período máximo de dois dias a partir da primeira tentativa de execução. Após a ultrapassagem de ambos os limites, a operação falha permanentemente.
  • No barqueue, o App Engine tenta repetir as tarefas, aumentando o intervalo linearmente entre cada repetição até atingir a retirada máxima e repetir indefinidamente no intervalo máximo (por isso, os intervalos entre os pedidos são 10 s, 20 s, 30 s, ..., 190 s, 200 s, 200 s, ...).
  • Em bazqueue, o intervalo de repetição começa em 10 s, depois duplica três vezes, aumenta linearmente e, finalmente, repete indefinidamente no intervalo máximo (por isso, os intervalos entre pedidos são 10 s, 20 s, 40 s, 80 s, 160 s, 240 s, 300 s, 300 s, ...).

Esta é a equivalência do Cloud Tasks de voltar a tentar tarefas nas filas de tarefas.

gcloud

Quando definir opções que especifiquem um número de segundos, tem de 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 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);
      }
    }
  }
}

Para saber mais, leia a referência do Cloud Tasks Defina parâmetros de repetição.

Eliminar tarefas de uma fila

Quando elimina uma tarefa, tem de aguardar 9 dias antes de criar uma tarefa com o mesmo nome se a tarefa estiver numa fila criada através de um ficheiro queue.yaml ou 1 hora se a tarefa estiver numa fila criada através do Cloud Tasks.

O exemplo seguinte elimina a tarefa com o ID da tarefa foo da fila com o ID da fila queue1. Esta é a ação equivalente no Cloud Tasks a eliminar tarefas nas filas de tarefas.

gcloud

O projeto e a localização da tarefa são inferidos a partir do projeto predefinido da CLI gcloud.

gcloud tasks delete foo --queue=queue1

biblioteca 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.");
    }
  }
}

Para saber mais, leia a referência do Cloud Tasks Eliminar uma tarefa de uma fila.

Eliminar tarefas

O exemplo seguinte limpa todas as tarefas da fila com o ID da fila foo . Este é o equivalente do Cloud Tasks à eliminação de tarefas nas filas de tarefas.

gcloud

O projeto e a localização da fila são inferidos a partir do projeto predefinido da CLI gcloud.

gcloud tasks queues purge 

foo

biblioteca 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.");
    }
  }
}

Para saber mais, leia a referência do Cloud Tasks Eliminar todas as tarefas de uma fila.

Um exemplo do Cloud Tasks em Java 8

O exemplo seguinte é uma configuração básica para criar uma fila e colocar uma tarefa na mesma com o Cloud Tasks. Assume que o programador criou um ficheiro pom.xml para especificar a dependência do Cloud Tasks, conforme descrito na secção Importar a biblioteca do cliente. Este é o equivalente do Cloud Tasks ao exemplo de uma fila de tarefas Java 8 nas filas de tarefas.

O ficheiro responsável pela criação e colocação em fila da tarefa cria uma tarefa e adiciona-a à fila predefinida através da biblioteca cliente do Cloud Tasks:

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 ficheiro que define o trabalhador processa a 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);
  }
}

O que se segue?