Esempio di una coda di attività Go

In questo esempio viene creata un'app che mostra un modulo HTML. Inserisci una stringa nella finestra di dialogo e fai clic su Add. L'app conta il numero di volte che inserisci qualsiasi stringa in questo modo.

L'app svolge le seguenti operazioni:

  • Quando fai clic su Add, il modulo utilizza una richiesta POSTHTTP per inviare la stringa all'app in esecuzione in App Engine. L'app raggruppa la stringa in un'attività e la invia alla coda predefinita.
  • La coda inoltra l'attività a un gestore di attività incluso, mappato all'URL /worker, che scrive la stringa in un datastore in modo asincrono.
  • Quando invii una richiesta GET HTTP, viene visualizzato un elenco delle stringhe inserite e il numero di volteAdd di ciascuna stringa, digitandola o facendo clic sulla stessa nel menu a discesa.

Per eseguire il deployment di questa applicazione in App Engine:

  1. Copia quanto segue in un file denominato queue.yaml. In questo modo, la frequenza di elaborazione delle attività passa dal valore predefinito di 5 al secondo a 3 al secondo.

    queue:
    - name: default
      rate: 3/s
    
  2. Nella stessa directory, copia quanto segue in un file denominato come preferisci (che termina con .go). Si tratta del codice dell'applicazione, incluso il gestore delle attività.

    
    package counter
    
    import (
    	"html/template"
    	"net/http"
    
    	"google.golang.org/appengine"
    	"google.golang.org/appengine/datastore"
    	"google.golang.org/appengine/log"
    	"google.golang.org/appengine/taskqueue"
    )
    
    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)
    			return
    		}
    	}
    	q := datastore.NewQuery("Counter")
    	var counters []Counter
    	if _, err := q.GetAll(ctx, &counters); err != nil {
    		http.Error(w, err.Error(), http.StatusInternalServerError)
    		return
    	}
    	if err := handlerTemplate.Execute(w, counters); err != nil {
    		http.Error(w, err.Error(), http.StatusInternalServerError)
    		return
    	}
    	// 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)
    		return
    	}
    	counter.Count++
    	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>
    {{end}}
    <p>Start a new counter:</p>
    <form action="/" method="POST">
    <input type="text" name="name">
    <input type="submit" value="Add">
    </form>
    `
    
  3. Nella stessa directory, copia quanto segue in un file denominato app.yaml. Questa operazione configura la tua applicazione per App Engine:

    runtime: go
    api_version: go1
    
    handlers:
    - url: /worker/.*
      script: _go_app
      login: admin
    - url: /.*
      script: _go_app
  4. Assicurati di avere preparato un progetto Google Cloud Platform con un'app App Engine e di aver inizializzato e configurato il comando gcloud per tale progetto.

  5. Utilizza il comando gcloud app deploy per eseguire il deployment dell'app in App Engine.

  6. Guarda l'app in azione usando il comando gcloud app browse.