Насколько я понимаю, использование @ndb.toplevel заставляет обработчик ждать завершения всех асинхронных операций перед выходом. Из документов:
Для удобства вы можете украсить обработчик запроса @ndb.toplevel. Это говорит обработчику не выходить, пока его асинхронные запросы не будут завершены. Это, в свою очередь, позволяет вам отправить запрос и не беспокоиться о результате. https://developers.google.com/appengine/docs/python/ndb/async#intro
Таким образом, добавив @ndb.toplevel, ответ на самом деле не будет возвращен до тех пор, пока не завершится выполнение асинхронных методов. Использование @ndb.toplevel устраняет необходимость вызывать get_result для всех запущенных асинхронных вызовов (для удобства). Исходя из этого, запрос по-прежнему будет возвращать 500, если асинхронные запросы завершатся неудачно, потому что все асинхронные запросы должны быть завершены перед возвратом. Обновлено: ниже
Если вы используете задачу (я предполагаю, что вы имеете в виду очередь задач), очередь задач повторит запрос, если запрос не будет выполнен. Таким образом, ваш обработчик может быть чем-то вроде:
def get(self):
deferred.defer(execute_stuff_in_background, param,param1)
template.render(...)
а execute_stuff_in_background выполнит все дорогостоящие операции после возврата обработчика. Если в задаче возникнет конфликт, ваш исходный обработчик все равно вернет 200.
Если вы подозреваете, что возникнет конфликт, рассмотрите возможность сегментирования или использования реализации очереди fork-join для обработки записей (см. реализацию здесь: http://www.youtube.com/watch?v).=zSDC_TU7rtc#t=41m35)
Редактировать: краткий ответ Запрос завершится неудачно (возвратит 500), если асинхронные запросы не пройдут, потому что @ndb.toplevel ожидает завершения всех результатов перед выходом. Обновлено:Посмотрев на ответ @alexis ниже, я повторно запустил свой первоначальный тест (где я отключил запись в хранилище данных и вызвал put_async в обработчике, украшенном @ndb.toplevel), response периодически поднимает 500 (я предполагаю, что это зависит от времени выполнения). Основываясь на этом и ответе @alexis ниже, не ожидайте, что результат будет 500, если асинхронная задача выдает исключение, а вызывающая функция украшена @ndb.toplevel
person
Rob Curtis
schedule
01.09.2012