我正在尝试掌握 NDB 引入的异步操作,我想使用@ndb.tasklet
来异步我的一些工作。
简单的例子是在被覆盖的 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