Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork34.2k
Description
Bug report
Bug description:
Short Version
Adding_clock_resolution in this line has no effect (at least on linux):
cpython/Lib/asyncio/base_events.py
Line 1987 in88b5c66
| end_time=self.time()+self._clock_resolution |
Becausetime() returns a float of the current epoch time, and clock resolution is1e-9,self.time() == self.time() + self._clock_resolution, due to floating point precision loss. In a corner case whereself.time() matches the next scheduled timerexactly, it would have to wait for the next iteration of the event loop to get run.
Longer Version
I was writing deterministic unittests involving timers and asyncio. I used a VirtualClock which would mock outloop.time() andloop.select():
https://aiotools.readthedocs.io/en/latest/_modules/aiotools/timer.html#VirtualClock
The internal time does not advance unless a timer is awaited.
Unfortunately when using realistic timestamps, because of the precision loss described above, the event loop gets permanently stuck at the exact time of the next timer, and never advances.
In the snippet below, the problem is thathandle._when >= end_time is always true:
cpython/Lib/asyncio/base_events.py
Lines 1986 to 1994 in88b5c66
| # Handle 'later' callbacks that are ready. | |
| end_time=self.time()+self._clock_resolution | |
| whileself._scheduled: | |
| handle=self._scheduled[0] | |
| ifhandle._when>=end_time: | |
| break | |
| handle=heapq.heappop(self._scheduled) | |
| handle._scheduled=False | |
| self._ready.append(handle) |
This was introduced in this change:
ed1654f
CPython versions tested on:
3.10
Operating systems tested on:
Linux
Metadata
Metadata
Assignees
Projects
Status