Exemple de file d'attente de tâches Go

Cet exemple crée une application qui affiche un formulaire HTML. Saisissez une chaîne dans la boîte de dialogue et cliquez sur Add. L'application compte le nombre de fois où vous ajoutez une chaîne de cette manière.

L'application effectue les actions suivantes :

  • Lorsque vous cliquez sur Add, le formulaire utilise une requête HTTP POST pour envoyer la chaîne à l'application en cours d'exécution sur App Engine. L'application regroupe alors la chaîne dans une tâche et l'envoie à la file d'attente par défaut.
  • La file d'attente transmet la tâche à un gestionnaire de tâches intégré, mappé à l'URL /worker, qui écrit la chaîne dans un datastore de manière asynchrone.
  • L'envoi d'une requête HTTP GET affiche la liste des chaînes que vous avez saisies et le nombre de fois que vous avez Add chaque chaîne, soit en la saisissant, soit en cliquant dessus dans la liste déroulante.

Pour déployer cette application sur App Engine :

  1. Copiez le code ci-dessous dans un fichier nommé queue.yaml. Cela fait passer le taux de traitement des tâches de cinq par seconde à trois par seconde.

    queue:
    - name: default
      rate: 3/s
    
  2. Dans le même répertoire, copiez ce qui suit dans un fichier sous le nom de votre choix (en terminant par .go). Il s'agit du code de l'application, y compris le gestionnaire de tâches.

    
    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. Dans le même répertoire, copiez ce qui suit dans un fichier nommé app.yaml. Ceci configure votre application pour App Engine :

    runtime: go
    api_version: go1
    
    handlers:
    - url: /worker/.*
      script: _go_app
      login: admin
    - url: /.*
      script: _go_app
  4. Assurez-vous de disposer d'un projet Google Cloud Platform avec une application App Engine, et d'avoir initialisé et configuré la commande gcloudgcloud pour ce projet.

  5. Utilisez la commande gcloud app deploy pour déployer l'application sur App Engine.

  6. Utilisez la commande gcloud app browse pour voir l'application en action.