Esempio di una coda di attività Go

Questo esempio crea un'app che mostra un modulo HTML. Inserisci una stringa nella finestra di dialogo e fai clic su Add. L'app conteggia il numero di volte in cui inserisci una stringa in questo modo.

L'app esegue le seguenti operazioni:

  • Quando fai clic su Add, il modulo utilizza una richiesta HTTP POST per inviare la stringa all'app in esecuzione su App Engine. L'app raggruppa la stringa in un'attività e la invia alla coda predefinita.
  • La coda inoltra l'attività a un gestore delle attività incluso, mappato all'URL /worker, che scrive in modo asincrono la stringa in un archivio dati.
  • L'invio di una richiesta GET HTTP mostra un elenco delle stringhe che hai inserito e il numero di volte in cui haiAdd ogni stringa, digitandola o facendo clic su di essa nella casella a discesa.

Per eseguire il deployment di questa app in App Engine:

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

    queue:
    - name: default
      rate: 3/s
    
  2. Nella stessa directory, copia il seguente codice in un file denominato come preferisci (che termina con .go). Si tratta del codice dell'applicazione, incluso l'handler 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. In questo modo, l'applicazione viene configurata 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 con un'app App Engine e di aver inizializzato e configurato il comando gcloud per il progetto.

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

  6. Per vedere l'app in azione, utilizza il comando gcloud app browse.