google.appengine.ext.ndb.tasklets モジュール
概要
タスクレット デコレータ。
タスクレットは、スレッドを使わずに同時に実行している関数を記述する方法の 1 つです。タスクレットはイベントループによって実行され、yield ステートメントを使って、I/O でオペレーションや他の処理のために自ら停止することができます。ブロッキング オペレーションの概念は Future クラスに抽象化されますが、タスクレットは RPC が完了するのを待つために、RPC の yield を行う場合もあります。
@tasklet デコレータは、ジェネレータ関数をラップするため、呼び出されるとジェネレータがイベントループによって実行されている間に Future が返されます。タスクレット内では、Future の yield が Future の結果を待って返します。次に例を示します。
@tasklet
def foo():
a = yield <some Future>
b = yield <another Future>
raise Return(a + b)
def main():
f = foo()
x = f.get_result()
print x
get_result() を使用して Future の結果が利用可能になるまでブロックするのは、多少非効率的であるので注意が必要です(ただし、ビジー待機ではありません)。ほとんどの場合、そのようなコードは代わりにタスクレットとして書き直します。
@tasklet
def main_tasklet():
f = foo()
x = yield f
print x
タスクレットを呼び出すと、イベントループで自動的にスケジュールされます。
def main():
f = main_tasklet()
eventloop.run() # Run until no tasklets left to do
f.done() # Returns True
特殊機能として、ラップされた関数がジェネレータ関数でない場合、その戻り値は Future を介して返されます。これにより、次の 2 つが同等になります。
@tasklet
def foo():
return 42
@tasklet
def foo():
if False: yield # The presence of 'yield' makes foo a generator
raise Return(42) # Or, after PEP 380, return 42
(Monocle に着想を得ている)この機能は、タスクレットを期待するインターフェースを実装しているが、一時停止する必要がない場合に便利です。タスクレットをジェネレータにするためにダミーの yield を挿入する必要はありません。
目次
- google.appengine.ext.ndb.tasklets.Return
-
StopIteration のエイリアス
- google.appengine.ext.ndb.tasklets.tasklet(func)ソース
- google.appengine.ext.ndb.tasklets.synctasklet(func)ソース
-
呼び出されたときにタスクレットとして機能するデコレータ。
これを使用して、ウェブ アプリケーション フレームワーク(Django ビュー関数や webapp.RequestHandler.get メソッドなど)によって呼び出されるリクエスト ハンドラ関数をラップします。
- google.appengine.ext.ndb.tasklets.toplevel(func)ソース
-
新しいデフォルト Context を設定する同期タスクレット。
webapp.RequestHandler.get() や Django ビュー関数などのトップレベル ビュー関数にこれを使用します。
- google.appengine.ext.ndb.tasklets.sleep(dt)ソース
指定した時間だけスリープ状態になる公開関数。
例yield tasklets.sleep(0.5) # 0.5 秒スリープ。
- google.appengine.ext.ndb.tasklets.add_flow_exception(exc)ソース
-
ログに記録されない例外を追加します。
引数は Exception のサブクラスでなければなりません。
- google.appengine.ext.ndb.tasklets.get_return_value(err)ソース
- google.appengine.ext.ndb.tasklets.get_context()ソース
- google.appengine.ext.ndb.tasklets.set_context(new_context)ソース
- google.appengine.ext.ndb.tasklets.make_default_context()ソース
- google.appengine.ext.ndb.tasklets.make_context(*args, **kwds)ソース
- class google.appengine.ext.ndb.tasklets.Future(info=None)ソース
-
ベース: オブジェクト
Future には 0 以上のコールバックがあります。
コールバックは、結果の準備が整うと呼び出されます。
注: 多少の着想は含まれていますが、PEP 3148 で定義された Future インターフェースに準拠していません。また、着想を含む(多少互換性を持たせようとする)App Engine 固有の UserRPC クラスと MultiRpc クラスです。
- FINISHING = 2
- IDLE = 0
- RUNNING = 1
- add_callback(callback, *args, **kwds)ソース
- add_immediate_callback(callback, *args, **kwds)ソース
- check_success()ソース
- done()ソース
- dump()ソース
- dump_stack()ソース
- get_exception()ソース
- get_result()ソース
- get_traceback()ソース
- set_exception(exc, tb=None)ソース
- set_result(result)ソース
- state
- wait()ソース
- classmethod wait_all(futures)ソース
- classmethod wait_any(futures)ソース
- class google.appengine.ext.ndb.tasklets.MultiFuture(info=None)ソース
-
ベース: google.appengine.ext.ndb.tasklets.Future
他の複数の Future に依存する Future。
これは「v1、v2、… = yield f1、f2、…」によって内部的に使用されます。セマンティクス(例えば、エラー処理)は、そのユースケースによって制約されます。
呼び出し元の POV からのプロトコルは次のとおりです。
mf = MultiFuture() mf.add_dependent(<some other Future>) -OR- mf.putq(<some value>) mf.add_dependent(<some other Future>) -OR- mf.putq(<some value>) . . (More mf.add_dependent() and/or mf.putq() calls) . mf.complete() # No more dependents will be added. . . (Time passes) . results = mf.get_result()
results はすべての従属 Future の結果のリストで、追加された順に表示されています。
同じ従属 Future を複数回追加できます。
コールバックはいつでも追加できます。
従属 Future POV から、何もする必要はありません。コールバックは自動的に各従属 Future に追加され、MultiFuture へ追加の完了を知らせます。
エラー処理: 従属 Future がエラーになると、mf に伝播します。早期エラーを強制するには、mf.complete() の代わりに mf.set_Exception() を呼び出すことができます。その後は、mf.add_dependencies() または mf.putq() を呼び出すことはできません。
- add_dependent(fut)ソース
- complete()ソース
- putq(value)ソース
- set_exception(exc, tb=None)ソース
- class google.appengine.ext.ndb.tasklets.QueueFuture(info=None)ソース
-
ベース: google.appengine.ext.ndb.tasklets.Future
MultiFuture と同じプロトコルに従うキュー。
ただし、結果をリストとして返す代わりに、準備ができたらすぐに getq() を使用して取得できます。最後の結果が準備できると、Future 自体は(結果の取得に関係なく)None という結果で終了します。
getq() メソッドは、次の結果が準備できるまでブロックする Future を返し、その結果を返します。getq() 呼び出しはそれぞれ、一意の結果を 1 つ取得します。最後の結果が返された後にさらに getq() を呼び出すと、Future の例外として EOFError が返されます(つまり、q.getq() は常に Future を返しますが、Future は EOFError を発生させます)。
注: 値は .putq(value) を使用して直接プッシュすることもできます。ただし、フロー制御はありません。プロデューサーがコンシューマよりも高速であれば、キューは無制限に拡大します。
- add_dependent(fut)ソース
- complete()ソース
- getq()ソース
- putq(value)ソース
- set_exception(exc, tb=None)ソース
- class google.appengine.ext.ndb.tasklets.SerialQueueFuture(info=None)ソース
-
ベース: google.appengine.ext.ndb.tasklets.Future
QueueFuture と似ていますが、挿入順序は維持されます。
このクラスは、クエリ オペレーションで使用されます。
不変条件:
-
_queue と _waiting の少なくとも 1 つは空です。
-
_waiting の Future は常に保留中です。
(_queue の Future は保留中または完了している可能性があります)
以下の説明では、add_dependent() は putq() と同様に扱われています。
putq() が getq() よりも前にある場合、次のようになります。
putq() v
_queue: [f1, f2, …]; _waiting: [] ^ getq()
ここで、putq() は _queue の右側に Future を追加し、getq() は左側から Future を削除します。
getq() が putq() よりも前にある場合、次のようになります。
putq() v
- _queue: []; _waiting: [f1, f2, …]
-
^ getq()
ここで、putq() は _waiting の左側から Future を削除し、getq() は Future を右側に追加します。
両方が空の場合、putq() は _queue の右側に Future を追加し、getq() は _waiting の右側に Future を追加します。
_full フラグは、putq() がそれ以上呼び出されなくなることを意味します。complete() または set_exception() のいずれかを呼び出して設定されます。
complete() を呼び出すと、putq() がそれ以上呼び出されなくなります。 getq() が後ろにあると、後続の getq() 呼び出しは空になるまで _queue を使い果たし、その後は EOFError を渡す Future を返します(getq() 自体は EOFError を発生させません)。 complete() が呼び出されたときに getq() が先行していると、_waiting の Future はすべて EOFError 例外を受け取ります(それによって _waiting を使い果たします)。
complete() の代わりに set_exception() が呼び出された場合、そこで設定された例外とトレースバックが EOFError の代わりに使用されます。
- add_dependent(fut)ソース
- complete()ソース
- getq()ソース
- putq(value)ソース
- set_exception(exc, tb=None)ソース
-
- class google.appengine.ext.ndb.tasklets.ReducingFuture(reducer, infoType=None, batch_size=20)ソース
-
ベース: google.appengine.ext.ndb.tasklets.Future
MultiFuture と同じプロトコルに従うキュー。
ただし、結果は、従属 Future の結果のリストではなく、「レデューサ」タスクレットを呼び出すことによって計算されます。レデューサ タスクレットには値のリストが必要で、1 つの値を返します。値のサブリストに対して複数回呼び出すことができ、sum() などのように動作します。
注: レデューサ入力値は、キューに追加された順序と比較して並べ替えることができます。
- add_dependent(fut)ソース
- complete()ソース
- putq(value)ソース
- set_exception(exc, tb=None)ソース