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 conta 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 di attività incluso, mappato all'URL /worker, che scrive in modo asincrono la stringa in un datastore.
  • L'invio di una richiesta HTTP GET mostra un elenco delle stringhe che hai inserito e il numero di volte in cui haiAddato 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 velocità di elaborazione delle attività passerà 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 con il nome che preferisci (che termina con .go). Questo è il 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 il seguente codice in un file denominato app.yaml. In questo modo configuri 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 un progetto Google Cloud con un'app App Engine preparato 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 su App Engine.

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