En esta página, se muestra cómo crear tareas de App Engine de manera programática y colocarlas en colas de Cloud Tasks. Con este proceso, puedes especificar explícitamente el servicio y el controlador que deberían procesar la tarea y, de manera opcional, transferir los datos específicos de la tarea al controlador.
También puedes ajustar la configuración de la tarea, como programar una hora en el futuro en la que se debe ejecutar o limitar la cantidad de veces que deseas que se reintente la tarea si falla. Si eliges especificar un nombre para la tarea, Cloud Tasks puede usar ese nombre a fin de garantizar la anulación de la duplicación de tareas, aunque el procesamiento necesario puede agregar mayor latencia.
Puedes crear tareas en forma de una solicitud HTTP, que puedes construir como quieras. Sin embargo, el uso de las bibliotecas cliente de Google Cloud, como las siguientes muestras, puede ayudarte a administrar los detalles de una comunicación de bajo nivel con el servidor, incluida la autenticación con Google.
C#
using Google.Cloud.Tasks.V2;
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using System;
class CreateAppEngineTask
{
public string CreateTask(
string projectId = "YOUR-PROJECT-ID",
string location = "us-central1",
string queue = "my-queue",
string payload = "Hello World!",
int inSeconds = 0)
{
CloudTasksClient client = CloudTasksClient.Create();
QueueName parent = new QueueName(projectId, location, queue);
var response = client.CreateTask(new CreateTaskRequest
{
Parent = parent.ToString(),
Task = new Task
{
AppEngineHttpRequest = new AppEngineHttpRequest
{
HttpMethod = HttpMethod.Post,
RelativeUri = "/log_payload",
Body = ByteString.CopyFromUtf8(payload)
},
ScheduleTime = Timestamp.FromDateTime(
DateTime.UtcNow.AddSeconds(inSeconds))
}
});
Console.WriteLine($"Created Task {response.Name}");
return response.Name;
}
}
Python
"""Create a task for a given queue with an arbitrary payload."""
from google.cloud import tasks_v2
from google.protobuf import timestamp_pb2
import datetime
import json
# Create a client.
client = tasks_v2.CloudTasksClient()
# TODO(developer): Uncomment these lines and replace with your values.
# project = 'my-project-id'
# queue = 'my-appengine-queue'
# location = 'us-central1'
# payload = 'hello' or {'param': 'value'} for application/json
# in_seconds = None
# Construct the fully qualified queue name.
parent = client.queue_path(project, location, queue)
# Construct the request body.
task = {
'app_engine_http_request': { # Specify the type of request.
'http_method': tasks_v2.HttpMethod.POST,
'relative_uri': '/example_task_handler'
}
}
if payload is not None:
if isinstance(payload, dict):
# Convert dict to JSON string
payload = json.dumps(payload)
# specify http content-type to application/json
task["app_engine_http_request"]["headers"] = {"Content-type": "application/json"}
# The API expects a payload of type bytes.
converted_payload = payload.encode()
# Add the payload to the request.
task['app_engine_http_request']['body'] = converted_payload
if in_seconds is not None:
# Convert "seconds from now" into an rfc3339 datetime string.
d = datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(seconds=in_seconds)
# Create Timestamp protobuf.
timestamp = timestamp_pb2.Timestamp()
timestamp.FromDatetime(d)
# Add the timestamp to the tasks.
task['schedule_time'] = timestamp
# Use the client to build and send the task.
response = client.create_task(parent=parent, task=task)
print('Created task {}'.format(response.name))
return response
Ten en cuenta el archivo requirements.txt
:
Flask==2.0.2
gunicorn==20.1.0
google-cloud-tasks==2.7.1
Java
// Instantiates a client.
try (CloudTasksClient client = CloudTasksClient.create()) {
// Variables provided by the CLI.
// projectId = "my-project-id";
// queueName = "my-appengine-queue";
// location = "us-central1";
// payload = "hello";
// Construct the fully qualified queue name.
String queuePath = QueueName.of(projectId, location, queueName).toString();
// Construct the task body.
Task.Builder taskBuilder =
Task.newBuilder()
.setAppEngineHttpRequest(
AppEngineHttpRequest.newBuilder()
.setBody(ByteString.copyFrom(payload, Charset.defaultCharset()))
.setRelativeUri("/tasks/create")
.setHttpMethod(HttpMethod.POST)
.build());
if (params.hasOption(IN_SECONDS_OPTION.getOpt())) {
// Add the scheduled time to the request.
int seconds = Integer.parseInt(params.getOptionValue(IN_SECONDS_OPTION.getOpt()));
taskBuilder.setScheduleTime(
Timestamp.newBuilder()
.setSeconds(Instant.now(Clock.systemUTC()).plusSeconds(seconds).getEpochSecond()));
}
// Send create task request.
Task task = client.createTask(queuePath, taskBuilder.build());
System.out.println("Task created: " + task.getName());
}
Ten en cuenta el archivo pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2018 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<groupId>com.example.task</groupId>
<artifactId>appengine-tasks-j8</artifactId>
<!--
The parent pom defines common style checks and testing strategies for our samples.
Removing or replacing it should not affect the execution of the samples in anyway.
-->
<parent>
<groupId>com.google.cloud.samples</groupId>
<artifactId>shared-configuration</artifactId>
<version>1.2.0</version>
<relativePath></relativePath>
</parent>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
<dependencies>
<!-- Compile/runtime dependencies -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-tasks</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.5.0</version>
<scope>compile</scope>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.truth</groupId>
<artifactId>truth</artifactId>
<version>1.1.3</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<!-- for hot reload of the web application-->
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes
</outputDirectory>
<plugins>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<projectId>GCLOUD_CONFIG</projectId>
<version>GCLOUD_CONFIG</version>
<deploy.promote>true</deploy.promote>
<deploy.stopPreviousVersion>true</deploy.stopPreviousVersion>
</configuration>
</plugin>
<!-- <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.0</version>
</plugin> -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<mainClass>com.example.task.CreateTask</mainClass>
<cleanupDaemonThreads>false</cleanupDaemonThreads>
</configuration>
</plugin>
</plugins>
</build>
</project>
PHP
use Google\Cloud\Tasks\V2\AppEngineHttpRequest;
use Google\Cloud\Tasks\V2\CloudTasksClient;
use Google\Cloud\Tasks\V2\HttpMethod;
use Google\Cloud\Tasks\V2\Task;
/** Uncomment and populate these variables in your code */
// $projectId = 'The Google project ID';
// $locationId = 'The Location ID';
// $queueId = 'The Cloud Tasks App Engine Queue ID';
// $payload = 'The payload your task should carry to the task handler. Optional';
// Instantiate the client and queue name.
$client = new CloudTasksClient();
$queueName = $client->queueName($projectId, $locationId, $queueId);
// Create an App Engine Http Request Object.
$httpRequest = new AppEngineHttpRequest();
// The path of the HTTP request to the App Engine service.
$httpRequest->setRelativeUri('/task_handler');
// POST is the default HTTP method, but any HTTP method can be used.
$httpRequest->setHttpMethod(HttpMethod::POST);
// Setting a body value is only compatible with HTTP POST and PUT requests.
if (isset($payload)) {
$httpRequest->setBody($payload);
}
// Create a Cloud Task object.
$task = new Task();
$task->setAppEngineHttpRequest($httpRequest);
// Send request and print the task name.
$response = $client->createTask($queueName, $task);
printf('Created task %s' . PHP_EOL, $response->getName());
Ten en cuenta el archivo composer.json
:
{
"require": {
"google/cloud-tasks": "^1.4.0"
}
}
Go
// Command create_task constructs and adds a task to an App Engine Queue.
package main
import (
"context"
"fmt"
cloudtasks "cloud.google.com/go/cloudtasks/apiv2"
taskspb "google.golang.org/genproto/googleapis/cloud/tasks/v2"
)
// createTask creates a new task in your App Engine queue.
func createTask(projectID, locationID, queueID, message string) (*taskspb.Task, error) {
// Create a new Cloud Tasks client instance.
// See https://godoc.org/cloud.google.com/go/cloudtasks/apiv2
ctx := context.Background()
client, err := cloudtasks.NewClient(ctx)
if err != nil {
return nil, fmt.Errorf("NewClient: %v", err)
}
defer client.Close()
// Build the Task queue path.
queuePath := fmt.Sprintf("projects/%s/locations/%s/queues/%s", projectID, locationID, queueID)
// Build the Task payload.
// https://godoc.org/google.golang.org/genproto/googleapis/cloud/tasks/v2#CreateTaskRequest
req := &taskspb.CreateTaskRequest{
Parent: queuePath,
Task: &taskspb.Task{
// https://godoc.org/google.golang.org/genproto/googleapis/cloud/tasks/v2#AppEngineHttpRequest
MessageType: &taskspb.Task_AppEngineHttpRequest{
AppEngineHttpRequest: &taskspb.AppEngineHttpRequest{
HttpMethod: taskspb.HttpMethod_POST,
RelativeUri: "/task_handler",
},
},
},
}
// Add a payload message if one is present.
req.Task.GetAppEngineHttpRequest().Body = []byte(message)
createdTask, err := client.CreateTask(ctx, req)
if err != nil {
return nil, fmt.Errorf("cloudtasks.CreateTask: %v", err)
}
return createdTask, nil
}
Node.js
// Imports the Google Cloud Tasks library.
const {CloudTasksClient} = require('@google-cloud/tasks');
// Instantiates a client.
const client = new CloudTasksClient();
async function createTask() {
// TODO(developer): Uncomment these lines and replace with your values.
// const project = 'my-project-id';
// const queue = 'my-appengine-queue';
// const location = 'us-central1';
// const payload = 'Hello, World!';
// Construct the fully qualified queue name.
const parent = client.queuePath(project, location, queue);
const task = {
appEngineHttpRequest: {
httpMethod: 'POST',
relativeUri: '/log_payload',
},
};
if (payload) {
task.appEngineHttpRequest.body = Buffer.from(payload).toString('base64');
}
if (inSeconds) {
// The time when the task is scheduled to be attempted.
task.scheduleTime = {
seconds: inSeconds + Date.now() / 1000,
};
}
console.log('Sending task:');
console.log(task);
// Send create task request.
const request = {parent: parent, task: task};
const [response] = await client.createTask(request);
const name = response.name;
console.log(`Created task ${name}`);
}
createTask();
Ten en cuenta el archivo package.json
:
{
"name": "appengine-cloudtasks",
"description": "Google App Engine Cloud Tasks example.",
"license": "Apache-2.0",
"author": "Google Inc.",
"private": true,
"engines": {
"node": ">=10"
},
"files": [
"*.js"
],
"scripts": {
"test": "mocha",
"start": "node server.js"
},
"dependencies": {
"@google-cloud/tasks": "^2.5.0",
"body-parser": "^1.18.3",
"express": "^4.16.3"
},
"devDependencies": {
"chai": "^4.2.0",
"mocha": "^8.0.0",
"uuid": "^8.0.0"
}
}
Ruby
require "google/cloud/tasks"
# Create an App Engine Task
#
# @param [String] project_id Your Google Cloud Project ID.
# @param [String] location_id Your Google Cloud Project Location ID.
# @param [String] queue_id Your Google Cloud App Engine Queue ID.
# @param [String] payload The request body of your task.
# @param [Integer] seconds The delay, in seconds, to process your task.
def create_task project_id, location_id, queue_id, payload: nil, seconds: nil
# Instantiates a client.
client = Google::Cloud::Tasks.cloud_tasks
# Construct the fully qualified queue name.
parent = client.queue_path project: project_id, location: location_id, queue: queue_id
# Construct task.
task = {
app_engine_http_request: {
http_method: "POST",
relative_uri: "/log_payload"
}
}
# Add payload to task body.
if payload
task[:app_engine_http_request][:body] = payload
end
# Add scheduled time to task.
if seconds
timestamp = Google::Protobuf::Timestamp.new
timestamp.seconds = Time.now.to_i + seconds.to_i
task[:schedule_time] = timestamp
end
# Send create task request.
puts "Sending task #{task}"
response = client.create_task parent: parent, task: task
puts "Created task #{response.name}" if response.name
end
Próximos pasos
- Aprende a crear controladores de tareas de App Engine.
- Obtén más información sobre las tareas en la referencia de la API de RPC.
- Obtén más información sobre las tareas en la referencia de la API de REST.