Cloud Tasks でも deferred ライブラリが使いたい
ソフトウェアエンジニアの花岡です。deferred ライブラリとは、GAE/Python 2 SE における非同期処理ライブラリで
import logging
from google.appengine.ext import deferred
def do_something_expensive(a, b, c=None):
logging.info("Doing something expensive!")
# Do your work here
# Somewhere else
deferred.defer(do_something_expensive, "Hello, world!", 42, True)
のように書くことで、関数名の示すような時間のかかるタスクをリクエスト外で実行させることができます。
Task Queue の push queue を利用していて、以下のようにタスクが Task Queue に登録されワーカーがタスクを処理してくれます。
deferred ライブラリにはこのワーカーのための WSGI アプリケーションも実装されていて app.yaml に
- url: /_ah/queue/deferred
script: google.appengine.ext.deferred.deferred.application
login: admin
と書くことで個別にハンドラを実装しなくていいのもお手軽でした。
しかし Task Queue の push queue の移行先である Cloud Tasks では
In some cases where you might need a series of diverse small tasks handled asynchronously but you don’t want to go through the work of setting up individual distinct handlers, the App Engine SDK allows you to use runtime specific libraries to create simple functions to manage these tasks. This feature is not available in Cloud Tasks. Note, though, that normal tasks can be scheduled in the future using Cloud Tasks.
というように deferred ライブラリが提供されていません。
複雑な実装ではないため、Cloud Tasks のライブラリとして提供しないのは理由があるのかもしれませんが、deferred ライブラリのお手軽さはかなり便利だったので Task Queue ではなく Cloud Tasks を利用する deferred ライブラリ cloud-tasks-deferred を作ってみました。
Cloud Tasks ではターゲット(Task Queue でのワーカーに相当)は App Engine でなくてもいいのですが、簡単のために以下のような App Engine ターゲット用になっています。
cloud_tasks_deferred パッケージは deferred モジュールと wsgi モジュールからなります。
from google.appengine.ext import deferred
を
from cloud_tasks_deferred import deferred
に変えるだけで動けばいいなぁという思いで作りました。またタスクハンドラの WSGI アプリケーションとしては
google.appengine.ext.deferred.deferred.application
の代わりに
cloud_tasks_deferred.wsgi.application
が使えるようにしました。google.appengine.ext.deferred.deferred.application は GAE/Python 2 SE で利用可能だった webapp2 で実装されています。cloud_tasks_deferred.wsgi.application でも外部ライブラリに依存しないように PEP 3333 に準拠した application 関数を実装しました。
deferred ライブラリの基本的な仕組みはシンプルで、callable とその引数を pickle したものを含むタスクを作成し、それをハンドラで unpickle して実行するというものです。そのため非同期処理できる callable(と引数)には制限があります。詳しくは google.appengine.ext.deferred.deferred の module docstring に記載されています。
cloud-tasks-deferred では簡単のために実装を省略した部分が多々ありますが、Cloud Tasks を利用した deferred ライブラリの基本的な検証はできました。
以上、やってみた系の記事でした。
その他の記事
Other Articles
関連職種
Recruit