Message 209056 - Python tracker (original) (raw)
Guido van Rossum added the comment:
I've lost some context, but perhaps we should have the notion of "granularity" of the poll/select timeout (e.g. 1 msec), and consider events that are in the future by less than that granularity as ready? Then we can round the timeout down: if someone passes a timeout of 1.1 msec, poll would wait for approximately 1 msec, and when it returns the event would be considered "due now" as long as the balance (about 0.1 msec) was under 1 msec.
Well, it sounds like a good compromise according to my experimentation in my last commits on epoll and selectors.
New attached asyncio_granularity.patch:
- Restore the previous rounding method for poll and epoll (in select and selectors modules), remove unit tests which were designed to test the rounding the timeout away from zero
- Add a new resolution attribute to selectors.BaseSelector (select: 1e-6, poll and epoll: 1e-3, kqueue: 1e-9)
- Add a new granularity attribute to asyncio.BaseEventLoop: maximum of time resolution and selector resolution
- Add a unit test for asyncio counting the number of calls to _run_once(), independent of the selector and the platform
- BaseEventLoop._run_once() rounds the deadline and current time using granularity
I tested the patch on Linux, FreeBSD and Windows (select, selectors and asyncio tests pass). Granularity:
- Linux. poll, epoll: 1 ms, select: 1 us (resolution of time.monotonic: 1 ns)
- FreeBSD. poll: 1 ms, select: 1 us, kqueue: 11 ns (resolution of time.monotonic: 11 ns)
- Windows (tested on my Windows 7 VM): select, proactor: 15.6 ms (resolution of time.monotonic(): 15.6 ms)
BaseProactorEventLoop doesn't use the resolution of IocpProactor because I don't know the resolution :-) Anyway, time.monotonic() has a low resolution (15.6 ms) and so it should be fine.
If the patch is accepted, my changes on Python 3.3 should also be reverted.