Skip to content

Instantly share code, notes, and snippets.

@isdyy
Last active December 4, 2016 05:39
Show Gist options
  • Save isdyy/7a3861c11c7226d458cb to your computer and use it in GitHub Desktop.
Save isdyy/7a3861c11c7226d458cb to your computer and use it in GitHub Desktop.
GAE: Modules のリクエストルーティング, TaskQueue のTask 実行モジュールとバージョンについて

Modules のリクエストルーティング, TaskQueue のTask 実行モジュールとバージョンについて (2015.06)

Basics

リクエストのルーティングについて:

https://cloud.google.com/appengine/docs/python/modules/routing

  1. URLによるモジュール・バージョン(・インスタンス)指定
    • URL で module, version (, instance) を指定できる.
    • URL に module, version (, instance) を併記した指定は、dispatch.yaml の指定より優先される.
      • These two address forms are guaranteed to reach their target (if it exists). They will never be intercepted and rerouted by a pattern in the dispatch file:

      • https://instance-dot-version-dot-module-dot-app-id.appspot.com
      • https://version-dot-module-dot-app-id.appspot.com
  2. dispatch.yaml による指定
  3. デフォルト
    • URLでモジュール(or バージョン)だけ指定する・または指定しない.
    • dispatch.yaml に設定があればそちらのほうが優先される。
      • These address forms have a default routing behavior. Note that the default routing is overridden if there is a matching pattern in the dispatch file:

    • https://module-dot-app-id.appspot.com
    • https://version-dot-app-id.appspot.com
    • https://app-id.appspot.com
    • URL指定も設定もなければ default module の default version で実行される.
      • http://app-id.appspot.com/path

指定した module や version が存在しない場合は、デフォルトにフォールバックする(Not Found にはならない).

TaskQueue, Cron

TaskQueue (Push), Cron についてはそれぞれの yaml で target: を書いておくことができる。これを使って処理の種類によって実行 module をわけるということができる。(重たい画像処理をスペックの高いインスタンスで実行など)

queue.yaml, cron.yaml による指定:

  • queue毎、cron job毎に target を指定できる(target: "mymodule"). target はmodule, version, version.module のいずれかの値を取る.
  • 指定した target が prepend されたホストに対してリクエストが送信される.
    • The string is prepended to the domain name of your app when constructing the HTTP request for a task.

    • http://target.app-id.appspot.com
  • target に version.module と指定した場合も、target を prepend したホストに対してリクエストが送られる.
    • http://version.module.app-id.appspot.com

Task.target:

  • Task を enqueue する際に target を動的に指定できる。
  • taskqueue.add(target="..."), Task(target="...") など
  • ただし、queue.yaml に指定がある場合はこの引数は無視される。

target の指定が全くされていない場合は、Task を add した際のURL(module/version)が引き継がれる.

If target is unspecified, then tasks are invoked on the same version of the application where they were enqueued.
(https://cloud.google.com/appengine/docs/python/config/queue#target)

URLもデフォルトの場合は (Task実行時点での) default version で実行される.

Note that if the default application version changes between the time that the task is enqueued and the time that it executes, then the task will run in the new default version. (https://cloud.google.com/appengine/docs/python/config/queue#target)

appengine-pipelines では pipelineのワークフロー全体をつうじて start時のversion, module が引き継がれるつくりになっている模様.

Introspectively set the target so pipelines stick to the version it started. (https://github.com/GoogleCloudPlatform/appengine-pipelines/blob/master/python/src/pipeline/pipeline.py#L469-L471)

dispatch.yaml はリクエスト受信時のルーティングの設定だが、 TaskQueue, Cron の target はリクエストの送信先(どのホストにリクエストを送るか)を決める設定であり、処理のフェーズや実質が異なる.

queue.target vs dispatch

queue.yaml と dispatch.yaml の指定がバッティングする場合, dispatch の方が優先される.

Note: If you are using modules along with a dispatch file, your task's HTTP request may be intercepted and re-routed to another module. (https://cloud.google.com/appengine/docs/python/config/queue#target)

ただし、これは target 指定した queue の taskが http://target.app-id.appspot.com/path-to-task にリクエストされるため. このURL形式については上記の通り dispatch.yaml の指定が優先して適用される.

従って、queue.yaml の target に target: "version.module" とバージョン含めた指定をすると、リクエストURLが http://version.module.app-id.appspot.com/path-to-task となり、指定した通りの module / version で実行される.

Task invokation

タスクがどのURLでリクエストされ、どのモジュール・バージョンで実行されるかのまとめ.

  • target.myapp.appspot.com から enqueue した Task は...
    • -> Task(target="target") となる
      • IF: queue に target: mymodule2 と指定されている
        • -> mymodule2.myapp.appspot.com にリクエスト
          • -> デフォルトルーティングに従って処理される (dispatch があれば優先される)
      • IF: queue に target 指定がない
        • -> target.myapp.appspot.com にリクエスト
          • -> デフォルトルーティングに従って処理される (dispatch があれば優先される)
  • myversion.mymodule.myapp.appspot.com から enqueue した Task は...
    • -> Task(target="myversion.mymodule") となる
      • IF: queue に target: "mymodule2" と指定されている
        • -> mymodule2.myapp.appspot.com にリクエスト
          • -> デフォルトルーティングに従って処理される (dispatch があれば優先される)
      • IF: queue に target 指定がない
        • -> myversion.mymodule.myapp.appspot.com にリクエスト
          • -> myversion.mymodule で実行される
  • myapp.appspot.com から enqueue した Task は...
    • -> Task(target=taskqueue.DEFAULT_APP_VERSION)
      • IF: queue に target 指定がある
        • -> 同上
      • IF: queue に指定がない
        • -> デフォルトルーティングに従って処理される (dispatch があれば優先される)

Notes

  • queue.yaml の target 指定
    • Pros
      • queue ごと = 処理の種類ごとに Module を変えられる柔軟性がある
      • プログラムコードの変更なしでモジュールを変更できる(TaskQueue 利用箇所で queue をこまめに指定している前提)
    • Cons
      • Task追加時の暗黙のversion引き継ぎも無効になるので、defaultバージョン (or queueで指定したバージョン) 固定に(ほぼ)なる. 1 application 内で複数の version を運用する(開発や検証用の環境など) のには向かない.
  • dispatch.yaml
    • Pros
      • URL単位で Module を切り替えられるので手軽
      • プログラムの変更なしでモジュールを変更できる (URLがきれいに分割されている前提)
    • Cons
      • deferred, mapreduce, pipeline など、同じ URL で多様な処理をするものの扱いに困る
      • 単純な glob しか指定できないので、複雑な構成は作れない (-> Pros?)
      • ... が、max 10 rules という制限があるのでむやみにつかえない
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment