Я использую службу с высокой степенью параллелизма и в одном месте кода использую блокировку asyncio.Semaphore
. Я вижу множество CancelledErrors, подобных этому:
File xxx.py
async with my_semaphore:
File /usr/local/lib/python3.7/asyncio/locks.py, line 92, in __aenter__
await self.acquire()
File /usr/local/lib/python3.7/asyncio/locks.py, line 474, in acquire
await fut
concurrent.futures._base.CancelledError
После проверки исходного кода создается впечатление, что это происходит, когда возникает исключение во время ожидания будущего, которое действует как блокировка.
С asyncio/locks.py:L483-L504
:
async def acquire(self):
"""Acquire a semaphore.
If the internal counter is larger than zero on entry,
decrement it by one and return True immediately. If it is
zero on entry, block, waiting until some other coroutine has
called release() to make it larger than 0, and then return
True.
"""
while self._value <= 0:
fut = self._loop.create_future()
self._waiters.append(fut)
try:
await fut
except:
# See the similar code in Queue.get.
fut.cancel()
if self._value > 0 and not fut.cancelled():
self._wake_up_next()
raise
self._value -= 1
return True
Этот код очень смущает меня. Почему это необходимо и в каких случаях может быть исключение в ожидании этого будущего? Разве исключения не улавливаются методом __exit__
диспетчера контекста? Я пытаюсь понять, как избавиться от этих ошибок.
РЕДАКТИРОВАТЬ: Возможно ли, что эти ошибки вызваны системой недостаточно памяти?