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: /.*
  script: _go_app
- url: /worker/.*
  script: _go_app
  login: admin

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

Monitor your resources on the go

Get the Google Cloud Console app to help you manage your projects.

Send feedback about...

App Engine standard environment for Go