@ndb.tasklet
NDB で導入された非同期操作を把握しようとしています。自分の作業の一部を非同期に使用したいと考えています。
簡単な例は、オーバーライドされた string_id の生成です。get_or_insert_async
これは物事への正しい方法ですか?ここで何を改善できますか?
@classmethod
@ndb.tasklet
def get_or_insert_async(cls, *args):
id = cls.make_string_id(*args)
model = yield super(MyModel, cls).get_or_insert_async(id)
raise ndb.Return(model)
別の例は、ファンアウトのような方法でループ内で何かを行うことです。これは正しいです?
@classmethod
@ndb.tasklet
def do_stuff(cls, some_collection):
@ndb.tasklet
def internal_tasklet(data):
do_some_long_taking_stuff(data)
id = make_stuff_needed_for_id(data)
model = yield cls.get_or_insert_async(id)
model.long_processing(data)
yield model.put_async()
raise ndb.Return(None)
for data in some_collection:
# will it parallelise internal_tasklet execution?
yield internal_tasklet(data)
raise ndb.Return(None)
編集:
全体の概念が理解されているように、(可能な場合) 並行して収集され、非同期的に実行されるオブジェクトをyields
提供するためにここにあります。Future
私は正しいですか?
ニックのヒントの後 (それはあなたが意図したものですか?):
@classmethod
@ndb.tasklet
def do_stuff(cls, some_collection):
@ndb.tasklet
def internal_tasklet(data):
do_some_long_taking_stuff(data)
id = make_stuff_needed_for_id(data)
model = yield cls.get_or_insert_async(id)
model.long_processing(data)
raise ndb.Return(model) # change here
models = []
for data in some_collection:
# will it parallelise internal_tasklet execution?
m = yield internal_tasklet(data) # change here
models.appedn(m) # change here
keys = yield ndb.put_multi_async(models) # change here
raise ndb.Return(keys) # change here
編集:
新しい改訂版…</p>
@classmethod
@ndb.tasklet
def do_stuff(cls, some_collection):
@ndb.tasklet
def internal_tasklet(data):
do_some_long_taking_stuff(data)
id = make_stuff_needed_for_id(data)
model = yield cls.get_or_insert_async(id)
model.long_processing(data)
raise ndb.Return(model)
futures = []
for data in some_collection:
# tasklets won't run in parallel but while
# one is waiting on a yield (and RPC underneath)
# the other will advance it's execution
# up to a next yield or return
fut = internal_tasklet(data)) # change here
futures.append(fut) # change here
Future.wait_all(futures) # change here
models = [fut.get_result() for fut in futures]
keys = yield ndb.put_multi_async(models) # change here
raise ndb.Return(keys) # change here