エンティティを更新してデータストアに保存し、戻る前に追加の作業を実行する必要があるリクエストハンドラーがあります(バックグラウンドタスクのキューイングやjson-いくつかの結果のシリアル化など)。このコードを並列化して、エンティティの保存中に追加の作業が行われるようにします。
これが私のハンドラーコードの要約です:
class FooHandler(webapp2.RequestHandler):
@ndb.toplevel
def post(self):
foo = yield Foo.get_by_id_async(some_id)
# Do some work with foo
# Don't yield, as I want to perform the code that follows
# while foo is being saved to the datastore.
# I'm in a toplevel, so the handler will not exit as long as
# this async request is not finished.
foo.put_async()
taskqueue.add(...)
json_result = generate_result()
self.response.headers["Content-Type"] = "application/json; charset=UTF-8"
self.response.write(json_result)
ただし、Appstatsは、datastore.Put
RPCが次の後にシリアルに実行されていることを示していtaskqueue.Add
ます。
少し掘り下げてみると、RPCがすぐに発行されるのではなくndb.context.py
、put_async()
呼び出しが追加されることになります。AutoBatcher
したがって、すべての非同期呼び出しが完了するのを待つと、最終的_put_batcher
にフラッシュされると思います。toplevel
プットのバッチ処理には特定のシナリオで実際のメリットがあることを理解していますが、ここでの私の場合は、プットRPCをすぐに送信して、エンティティの保存中に他の作業を実行できるようにします。
そうした場合yield foo.put_async()
、Appstatsで同じウォーターフォールを取得しますがdatastore.Put
、残りの前に実行されます。
yield
ハンドラーがput_async()
呼び出しが完了するのを待ってから残りのコードを実行するので、これは予想されることです。
ndb.get_context().flush()
また、直後に呼び出しを追加しようとしましたfoo.put_async()
が、Appstatsによると、datastore.Put
とtaskqueue.BulkAdd
呼び出しはまだ並行して行われていません。
put_async()
だから私の質問は:自動バッチャーをバイパスしてRPCをすぐに発行するように呼び出しを強制するにはどうすればよいですか?