Выполнение сопрограммы Asyncio остановилось и не вернуло никакой ошибки
Я столкнулся со странным поведением в одном из моих приложений. Итак, у меня есть приложение, у которого есть POST
точка входа, которая получает список идентификаторов заказов и после обработки каждого заказа должна сообщать внешнему API о денежной стоимости каждого заказа. Итак, мы сделали следующее:
round_details_tasks = [
asyncio.create_task(
self.launch_individual_order_details(order),
name=f"task_order_{order.id}",
)
for order in active_orders
]
results = await asyncio.gather(*order_details_tasks, return_exceptions=True)
for task, result in zip(order_details_tasks, results):
if isinstance(result, Exception):
print(f"⚠️ Task '{task.get_name()}' raised an exception: {result}")
else:
print(f"✅ Task '{task.get_name()}' succeeded with result: {result}")
Функция launch_individual_order_details(order)
выполняет следующие действия и другую логику, отличную от I/O
, перед этим блоком:
logger.debug(f"Sending order details with success for order: {order.id}")
await order_service.send_order_request(order)
Внутри send_order_request
мы создаем запись в таблице с именем Transaction
с идентификатором заказа и соответствующей суммой заказа в состоянии ожидания и отправляем http-запрос, используя библиотеку aiohttp.CLient
. После этого мы обновляем статус транзакции на "Успешно", если ответ на запрос получен успешно, и на "ошибка", если запрос не выполнен.
Итак, проблема, с которой мы сталкиваемся, заключается в том, что когда наша система находится под относительной нагрузкой на наши модули, когда модуль использует 70% от установленных нами лимитов ЦП, мы замечаем, что некоторые из наших задач просто прерывают выполнение и не сообщают циклу обработки событий об этом. любая возможная ошибка.
Мы обнаружили это, потому что после некоторого нагрузочного тестирования мы запустили несколько скриптов для проверки статуса транзакции и заметили, что у некоторых идентификаторов заказов статус транзакции был только "ожидание", поэтому они даже не выполнили запрос к внешнему api. Кроме того, мы заметили, что все заказы, которые находились в этом состоянии, не отображались в журнале успешных заданий:
print(f"✅ Task '{task.get_name()}' succeeded with result: {result}").
и они также не отображаются в журнале задач с ошибками:
print(f"⚠️ Task '{task.get_name()}' raised an exception: {result}").
Кроме того, мы также настроили параметр event loop
для отладки журналов на значение true и не обнаружили никаких ошибок, связанных с этими задачами. Единственное, что мы обнаружили, это то, что выполнение достигает этого журнала:
logger.debug(f"Sending order details with success for order: {order.id}")
и что состояние транзакции для этого заказа создается с состоянием pending
, но больше никогда не обновляется.
Есть ли у кого-нибудь какие-либо идеи о том, почему могут происходить такие случаи?