You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
» venv2/bin/python3 aiohttp_bug.py
DEBUG:asyncio:Using selector: EpollSelector
Pool opening.
Pool open.
======== Running on http://0.0.0.0:8080 ========
(Press CTRL+C to quit)
^C <hangs here for ~60s>
The hang is only after we create the pool. If we don't create the pool, no hang.
It's very likely that all tasks which run forever will have been created by the time we have completed the application startup
This just seems incorrect? In particular, psycopg_pool has a background task that is taking care of various async things that it appears to queue up for that task. That task has an event, which I presume is triggered when the queue has something new.
Its code looks like this:
asyncdefrun(self) ->None:
"""Execute the events scheduled."""q=self._queuewhileTrue:
asyncwithself._lock:
now=monotonic()
task=q[0] ifqelseNoneiftask:
iftask.time<=now:
heappop(q)
else:
delay=task.time-nowtask=Noneelse:
delay=self.EMPTY_QUEUE_TIMEOUTself._event.clear()
iftask:
ifnottask.action:
breaktry:
awaittask.action()
exceptExceptionase:
logger.warning(
"scheduled task run %s failed: %s: %s",
task.action,
e.__class__.__name__,
e,
)
else:
# Block for the expected timeout or until a new task scheduledawaitself._event.wait_timeout(delay)
That last await self._event.wait_timeout(delay) is what I am talking about here. wait_timeout, when called, calls asyncio.wait_for, which creates a task.
This is done every time we hit the lock, and it happens after the app has started, too, so this event wait's task ends up in the tasks set that aiohttp waits on.
Note that aiohttp's wait on all other running tasks to finish occurs before we run the application cleanups, so the pool is still alive — i.e., we're not first giving the cleanup context an opportunity to close the pool.
Describe the bug
If I create a
psycopg_pool.AsyncConnectionPool
object,aiohttp
's Ctrl+C handler will hang while trying to handle the ^C.To Reproduce
The following minimal example reproduces the bug:
Run it, hit ^C:
The hang is only after we create the pool. If we don't create the pool, no hang.
The reason we hang is this bit:
aiohttp/aiohttp/web.py
Lines 313 to 318 in 04b1212
Here,
aiohttp
attempts to wait on tasks to finish?There's slightly more context here:
aiohttp/aiohttp/web.py
Lines 338 to 343 in 04b1212
This just seems incorrect? In particular,
psycopg_pool
has a background task that is taking care of various async things that it appears to queue up for that task. That task has an event, which I presume is triggered when the queue has something new.Its code looks like this:
That last
await self._event.wait_timeout(delay)
is what I am talking about here.wait_timeout
, when called, callsasyncio.wait_for
, which creates a task.This is done every time we hit the lock, and it happens after the app has started, too, so this event wait's task ends up in the
tasks
set thataiohttp
waits on.Note that aiohttp's wait on all other running tasks to finish occurs before we run the application cleanups, so the pool is still alive — i.e., we're not first giving the cleanup context an opportunity to close the pool.
Expected behavior
^C wraps up without hanging (for 60s).
Logs/tracebacks
Python Version
aiohttp Version
multidict Version
yarl Version
OS
Arch Linux
Related component
Server
Additional context
Code of Conduct
The text was updated successfully, but these errors were encountered: