Un ejemplo de lista de tareas en cola de Go

En este ejemplo, se crea una aplicación que muestra un formulario HTML. Debes ingresar una string en el cuadro de diálogo y hacer clic en Add. La app cuenta la cantidad de veces que ingresas una string de esta forma.

La app hace lo siguiente:

  • Si haces clic en Add, el formulario usa una solicitud HTTP POST para enviar la string a la aplicación que se está ejecutando en App Engine. Allí, la aplicación agrupa la string en una tarea y la envía a una cola predeterminada.
  • La cola reenvía la tarea a un controlador de tarea incluido, asignado a la URL /worker, que escribe la string de forma asíncrona en Datastore.
  • Si envías una solicitud GET HTTP, se muestra la lista de strings que ingresaste y la cantidad de veces que realizaste la operación Add con cada una, ya sea escribiéndola o haciendo clic en ella en el cuadro desplegable.

Para implementar esta aplicación en App Engine:

  1. Copia lo siguiente en un archivo llamado queue.yaml. Esto cambia la velocidad a la que se procesan las tareas de 5 por segundo (la configuración predeterminada) a 3 por segundo.

    queue:
    - name: default
      rate: 3/s
    
  2. En el mismo directorio, copia lo siguiente en un archivo con el nombre que desees (debe terminar en .go). Este es el código de la aplicación, incluido el controlador de tareas.

    
    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. En el mismo directorio, copia lo siguiente en un archivo llamado app.yaml. Esto configura tu aplicación para App Engine:

    runtime: go
    api_version: go1
    
    handlers:
    - url: /worker/.*
      script: _go_app
      login: admin
    - url: /.*
      script: _go_app
  4. Asegúrate de tener preparado un proyecto de Google Cloud Platform con una aplicación de App Engine y de que inicializaste y configuraste el comando de gcloud para ese proyecto.

  5. Usa el comando de gcloud app deploy para implementar la aplicación en App Engine.

  6. Puedes ver la aplicación en acción con el comando de gcloud app browser.

¿Te ha resultado útil esta página? Enviar comentarios:

Enviar comentarios sobre...

Entorno estándar de App Engine para Go