Go によるタスクキューの例

この例では、HTML フォームを表示するアプリを作成します。ダイアログ ボックスに文字列を入力して [Add] をクリックします。アプリは、このようにして文字列が入力された回数をカウントします。

アプリは次のことを行います。

  • [Add] をクリックすると、フォームは HTTP POST リクエストを使用して、App Engine で実行されているアプリに文字列を送信します。アプリは受け取った文字列をタスクにバンドルしてデフォルトのキューに送信します。
  • キューは、/worker という URL にマッピングされた組み込み済みのタスクハンドラにタスクを転送し、ハンドラは非同期でデータストアに文字列を書き込みます。
  • HTTP GET リクエストの送信により、キーをタイプするかまたはプルダウン ボックスでクリックして入力した文字列と各文字列の Add を実行した回数のリストが表示されます。

このアプリを App Engine にデプロイするには、次の手順を実行します。

  1. queue.yaml という名前のファイルに以下の行をコピーします。これにより、タスクの処理頻度がデフォルトの 1 秒あたり 5 件から 1 秒あたり 3 件に変更されます。

    queue:
    - name: default
      rate: 3/s

  2. 同じディレクトリで、.go で終わる任意の名前のファイルに以下の行をコピーします。これはタスクハンドラを含むアプリケーション コードです。

    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. 同じディレクトリで、app.yaml という名前のファイルに以下の行をコピーします。これにより、アプリケーションが App Engine 用に構成されます。

    runtime: go
    api_version: go1
    
    handlers:
    - url: /worker/.*
      script: _go_app
      login: admin
    - url: /.*
      script: _go_app

  4. App Engine アプリで使用する Google Cloud Platform プロジェクトが用意されており、そのプロジェクト用に gcloud コマンドが初期化および構成されていることを確認します。

  5. gcloud app deploy コマンドを使用して、App Engine にアプリをデプロイします。

  6. gcloud app browser コマンドを使用して、アプリが動作していることを確認します。

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Go の App Engine スタンダード環境