Skip to content

ianlewis/kombu-appengine-pullqueue

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

kombu-appengine-pullqueue

A kombu backend for the appengine pull queue API. This can be used to create consumers for tasks from the appengine pull queue API.

You can find out more about the pull task queue REST API here: https://developers.google.com/appengine/docs/python/taskqueue/rest/

Why Use It

Why use the pull task queue API?

There are some instances where you would like to use the pull queue API to perform tasks that are difficult or impossible to do on App Engine. Things like complicated processing of images or video, using libraries or software not available on App Engine, or long running CPU bound tasks.

Why use kombu?

kombu provides a pretty simple API for dealing with queues so it gives you a good starting point for creating a consumer that can process tasks. Kombu handles polling, routing, and management of tasks. And in the unlikely event you want to use some other queue system you can reuse your existing code by changing just a few options.

Setup

Using the App Engine pull queue REST API requires you to authenticate using OAuth. You first need set up your project in the Google cloud console.

Follow the directions here about how to set up and register credentials. When you register your application be sure to create a "Native" application.

https://developers.google.com/appengine/docs/python/taskqueue/rest/about\_auth

Once you have done that you can download the client_secrets.json file from the cloud console. Once you have the client_secrets.json, you can authenticate very simply using the provided authentication utility.

$ pullqueue_authenticate client_secrets.json credentials

A Simple Producer

A "producer" creates tasks and puts them on the task queue. These tasks are then processed by a "consumer". Let's look at what a simple producer looks like.

from kombu import Connection

conn = Connection(
    transport="kombu_appengine:Transport",
    transport_options={
        'project_name': "my_project",
        'credentials_file': "/path/to/credentials",
    }
)

with conn:
    queue = conn.SimpleQueue('pull-queue')
    while True:
        queue.put(json.dumps({'message': message}))
        time.sleep(1)

Here we use the SimpleQueue class from kombu. SimpleQueue has a very similar api to the native Queue class in python. This producer will create a new tasks on the task queue with a very simple JSON payload.

A Simple Consumer

A "consumer" processes tasks from the task queue and removes them once it is finished processing.

from kombu import Connection

conn = Connection(
    transport="kombu_appengine:Transport",
    transport_options={
        'project_name': 'my_project',
        'polling_interval': 5,
        'num_tasks': 15,
        'credentials_file': 'credentials',
    }
)

try:
    with conn:
        queue = conn.SimpleQueue('pull-queue')
        while True:
            msg = queue.get()
            message = json.loads(msg.body)
            print message['message']
            msg.ack()
except KeyboardInterrupt:
    print('Exiting.')

We lease the task using the get() method and process it. In this case we are simply printing the text message we received. After we are finished, we "acknowledge" we are finished by calling the ack() method on the returned message object. This deletes the task from the App Engine pull queue.

More Advanced Producers and Consumers

More advanced routing can be done using kombu's Producer and Consumer classes. Unless you are utilizing multiple pull queues and doing some complicated routing, you likely wouldn't need to do use these.

If you are queueing tasks from an App Engine application, then you will likely be using the App Engine SDK to queue your tasks anyway.

If you think you might need to do something complicated like use multiple queues with tasks processed by a single or multiple consumer then you should probably check out the documentation for kombu. http://ask.github.io/kombu/introduction.html#terminology

from kombu import Connection, Exchange, Queue

# Create the exchange and queue. These are used to route messages.
app_engine = Exchange("appengine", "direct", durable=True)
pull_queue = Queue("pull-queue", exchange=app_engine, routing_key="pull-queue")

conn = Connection(
    hostname='',
    userid='credentials',
    transport="kombu_appengine:Transport",
    transport_options={
        'project_name': 'my_project',
        'polling_interval': 5,
        'credentials_file': 'credentials',
    }
)

# Enqueue a task
text = "Hello World!"

with conn:
    # Declare the queue.
    pull_queue(conn.channel()).declare()

    with conn.Producer(exchange=app_engine, routing_key="pull-queue") as producer:
        producer.publish({'text': text})


    def process_msg(body, message):
        print body['text']
        # Acknowledge the message so the task is deleted
        message.ack()

    with conn.Consumer(video_queue, callbacks=[process_media]) as consumer:
        # Process messages and handle events on all channels
        while True:
            conn.drain_events()

Supported Transport Options

The kombu_appengine transport backend supports several options which can be set via the transport_options parameter to the Connection class.

Option Required Default Description
project_name required None The Google Cloud Console project
hrd_project optional True A boolean option specifying if the app is an HRD app in App Engine. This is used as a workaround for API issues. See this issue for details: https://code.google.com/p/googleappengine/issues/detail?id=10199
credentials_file required None The path to the credentials file created after authenticating.
polling_interval optional 1.0 The number of seconds between polling calls to the pull queue API.
num_tasks optional 1 The number of tasks to lease at once and buffer locally for consumption.

A Note About Celery

kombu is most often used with celery so I though it wise to add a little note about celery support. While the kombu API is supported, unfortunately, celery is not supported because of the inability to create queues via the pull queue API. Celery uses queues for interprocess communication and creates queues dynamically for that purpose.

In the end though, using the pull queue for interprocess communication may not be very performant anyway even if celery was supported. More research may be needed to have full support for celery.

About

A kombu backend for the appengine pull queue API

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages