Я пытаюсь обвести голову асинхронным api без особого успеха.NDB Async API и get_or_insert_async
Я довольно простая установка в своем проекте лаборатории. У меня есть модель, которая выглядит следующим образом:
class SearchIndex(model.Model):
name = model.StringProperty(required=True)
reference_list = model.KeyProperty(repeated=True)
И метод, который использует get_or_insert и проверки, если reference_list содержит ключ, если не добавить его. Под объектом является модель сущность и список представляет собой список строк [ «ABC», «DEF», «ГХИ»]
@classmethod
def store_list_in_index(cls, list, entity):
put_queue = []
for verb in list:
index_entity = cls._SEARCH_INDEX_DB_MODEL.get_or_insert(verb, name=verb)
if not entity.key in index_entity.reference_list:
index_entity.reference_list.append(entity.key)
put_queue.append(index_entity)
if put_queue:
ndb.put_multi_async(put_queue)
Это работало, как я хотел, но к looong времени. Если список был около 20-30 раз. Это заняло около 15-20 секунд.
Итак, я начал смотреть асинхронный апи. Но не очень далеко. Теперь он не хранит вещи в БД:
@classmethod
def store_list_in_index(cls, list, entity):
put_queue = []
async_queue = []
@tasklets.tasklet
def txn(verb, entity):
ent = yield cls._SEARCH_INDEX_DB_MODEL.get_or_insert_async(verb, name=verb)
if not entity.key in ent.reference_list:
ent.reference_list.append(entity.key)
put_queue.append(ent)
raise tasklets.Return(ent)
for verb in list:
en = txn(verb, entity)
if put_queue:
ndb.put_multi_async(put_queue)
Я не очень понимаю, где, в основном, так как я не понимаю концепцию тасклетами и доходности. Кто-нибудь имеет идею или может указать мне направление?
EDIT:
Я закончил с этим решением:
@classmethod
@ndb.tasklet
def get_or_insert_index_entity(cls, verb):
ent = yield cls._SEARCH_INDEX_DB_MODEL.get_by_id_async(verb)
if not ent:
key = ndb.Key(cls._SEARCH_INDEX_DB_MODEL, verb)
ent = cls._SEARCH_INDEX_DB_MODEL(key=key, name=verb)
yield ent.put_async()
raise ndb.Return(ent)
@classmethod
@ndb.tasklet
def txn(cls, verb, entity):
ent = yield cls.get_or_insert_index_entity(verb)
if not entity.key in ent.reference_list:
ent.reference_list.append(entity.key)
yield ent.put_async()
raise ndb.Return(ent)
@classmethod
def store_list_in_index(cls, list, entity):
put_queue = []
for verb in list:
put_queue.append(cls.txn(verb, entity))
И добавив @ ndb.toplevel в мой обработчик прибудете-запроса. И это быстрее!
Я также отправил этот вопрос на https://groups.google.com/forum/?fromgroups#!topic/appengine-ndb-discuss/L4DEsYdEwTE и включены некоторые дополнительные вопросы
Я подробно расскажу в списке appengine-ndb-discuss. –