A Go Task Queue Example

The following example defines a task handler (worker) that increments a counter in the datastore, mapped to the URL /worker. There is also a handler for an HTTP GET request that displays the current value of the counter, and a handler for an HTTP POST request that enqueues a task and returns. It's difficult to watch the counter increase if the queue is processing tasks quickly. Therefore, the push queue should customized using queue.yaml so its tasks are sent at the slow rate of one per second:

# Change the refresh rate of the default queue from 5/s to 1/s.
- name: default
  rate: 1/s

Here is the code for the application, including the task handler:

package counter

import (



func init() {
	http.HandleFunc("/", handler)
	http.HandleFunc("/worker", worker)

type Counter struct {
	Name  string
	Count int

func handler(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)
	if name := r.FormValue("name"); name != "" {
		t := taskqueue.NewPOSTTask("/worker", map[string][]string{"name": {name}})
		if _, err := taskqueue.Add(ctx, t, ""); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
	q := datastore.NewQuery("Counter")
	var counters []Counter
	if _, err := q.GetAll(ctx, &counters); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	if err := handlerTemplate.Execute(w, counters); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	// OK

func worker(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)
	name := r.FormValue("name")
	key := datastore.NewKey(ctx, "Counter", name, 0, nil)
	var counter Counter
	if err := datastore.Get(ctx, key, &counter); err == datastore.ErrNoSuchEntity {
		counter.Name = name
	} else if err != nil {
		log.Errorf(ctx, "%v", err)
	if _, err := datastore.Put(ctx, key, &counter); err != nil {
		log.Errorf(ctx, "%v", err)

var handlerTemplate = template.Must(template.New("handler").Parse(handlerHTML))

const handlerHTML = `
{{range .}}
<p>{{.Name}}: {{.Count}}</p>
<p>Start a new counter:</p>
<form action="/" method="POST">
<input type="text" name="name">
<input type="submit" value="Add">

app.yaml is attached here:

runtime: go
api_version: go1

- url: /worker/.*
  script: _go_app
  login: admin
- url: /.*
  script: _go_app

To try this example, just copy the above files in a folder and deploy them by gcloud app deploy.

Was this page helpful? Let us know how we did:

Send feedback about...

App Engine standard environment for Go