Is there a way to set up a task for a task dynamically using the App Engine Java runtime?

When starting a background task with the App Engine Python Runtime, you can specify a target for the queue that will send the task to run on a specific service, version, or instance:

task = taskqueue.add(
    url='/update_counter',
    target='worker',
    params={'amount': amount})

      

Is there a way to do this in Java? The documentation mentions the parametertarget

, but does not show an example on how to use it. The method Queue.add

has no option for target

. The class TaskOptions

has nothing like target

.

This question documents how to usetarget

, but the answer lies in setting it up in queue.xml

. I would like to select a target at runtime like Python.

+3


source to share


1 answer


TL; DR . It may be based on an earlier version of the documentation, but it is not covered in the latest version of the documentation.

Approach based on the latest documentation

As per the last post of the latest documentation regarding Push Queues (and as you mentioned), you can configure the target module, version queue.xml

per queue. If specified, a job request is sent to the specified target. As you've already described, this is a static configuration and doesn't really answer your question (describing just for the sake of completeness).

<?xml version="1.0" encoding="UTF-8"?>
  <queue-entries>
    <queue>
      <name>queue-blue</name>
      <target>v2.task-module</target>
    </queue>
    <queue>
      <name>queue-red</name>
      <rate>1/s</rate>
    </queue>
  </queue-entries>

      

In the documentation for creating tasks and specifying a worker's service, it describes the goal chosen for the task, but does not provide a clear description of how to specify it.

When a task is unloaded from the queue, the Task Queue service sends it to the worker service. Each task has a target and a URL that determines which service and handler will eventually execute the task.

target

The target specifies the service that will receive the HTTP request to complete the job. This is a string that specifies service / version / instance in any canonical form. Most commonly used:

service
version.service
instance.version.service

      

The target string is appended to the domain name of your application. There are three ways to set a goal for a task:

  • Explanation declares the goal when creating a task.
  • Include a target directive when defining a queue in queue.xml as in the definition of the above queue. All tasks added to the queue with a goal will use this goal, even if a different goal was assigned to the task during construction.
  • If no target is specified according to one of the two previous methods, then the target is the version of the service that terminates it. Please note that if you set the task from the default service and the version this way, and the default version is changed to the task will be executed in the new default version.

url

url

selects one of the target service handlers to execute the task.

url

must match one of the handler URL patterns in the target service. The URL can include query parameters if the task method GET

or PULL

. If no URL is specified, the default URL /_ah/queue/[QUEUE_NAME]

, where [QUEUE_NAME]

is the name of the task queue.

Based on the documentation above, if you look TaskOptions.Builder

, there is no way to specify a goal for a task. This might indicate missing documentation on how to specify the target, or it simply no longer needs to specify the target dynamically when adding a task to the queue. Take a look at the approach described below based on earlier documentation.

An approach based on earlier documentation



DISCLAIMER: I am mentioning here based on outdated information (I have provided sources below) and therefore may not work as expected and / or in the future.

You can use a header Host

to specify the module, version, and instance information that will receive the request.

To specify the module and version, you can:

Queue queue = QueueFactory.getQueue("QUEUE_NAME");
    queue.add(TaskOptions.Builder
            .withUrl("/url/path")
            .param("key", "PARAM")
            .header("Host",
                    ModulesServiceFactory.getModulesService().getVersionHostname("MODULE_NAME", "VERSION")));

      

To specify an instance you can do:

Queue queue = QueueFactory.getQueue("QUEUE_NAME");
    queue.add(TaskOptions.Builder
            .withUrl("/url/path")
            .param("key", "PARAM")
            .header("Host",
                    ModulesServiceFactory.getModulesService().getInstanceHostname("MODULE_NAME", "VERSION", "INSTANCE_NAME"));

      

I could not find this information in the current version of the App Engine documentation, but using the Wayback machine, I found this information from an earlier doc from Jan 1, 2016 that describes how to perform a Push task. It was discussed in a different context in this github issue .

Executing task execution

App Engine performs push tasks by sending HTTP POST requests to your app. Specifying asynchronous callbacks for programs as an HTTP request is sometimes referred to as a webhook. The webhook model allows efficient parallel processing.

The task URL defines the task handler and the module that starts the handler.

The handler is defined by the portion of the URL path (the straight line separating string after the hostname) that is specified by the url parameter in TaskOptions, which you include in your call to the Queue.add () method. The URL must be relative and local to the root directory of the application.

The module and version in which the handler is executed is determined by:

  • The Host header parameter in the TaskOptions that you include in your call to the Queue.add () method.
  • Target directive in queue.xml or queue.yaml file.

If you do not specify any of these parameters, the task will run in the same module / version in which it was queued, subject to these rules:

  • If the default version of the application runs the task, the task will be launched by default. Note that if the application closes the task and the default version changes before the task actually runs, the task will run in the new default version.

  • If a non-default version sets a task, the task will always run on the same version.

Note: If you use modules in conjunction with a submit file, the task url may be intercepted and redirected to another module.

The namespace in which the push task runs when the task is added to the queue. By default, the task will run in the current namespace of the process that created the task. You can override this behavior by explicitly setting the namespace before adding the task to the queue, as described in the layered page.

+3


source







All Articles