Hello,
sorry if I don’t use precise terminology, I am new to asyncio.
Is there a way to have the asyncio runner to use higher resolution timers on Windows?
I have a process that interfaces with some hardware. It needs to poll some status at a regular interval (of the order of a second), and react to commands received on a ZeroMQ socket. I realize this with two asyncio tasks: one that does the polling and yields execution to the other awaiting on a future scheduled with loop.call_at()
, and a second that awaits on socket.recv()
. Reacting to commands takes much less than the polling interval and all works nicely (and I am very happy about how easy it was to code this with asyncio).
The only drawback is that the timer used by the asyncio event loop is fairly coarse and I get ~20 ms jitter [1] in the polling interval. This is not terrible but I would like to investigate whether there is room for improvement. I don’t know much about the Windows API, thus I am not sure where the limitation comes from. Searching the 'net I found that Trio may be using higher resolution timers for his event loop, but ZeroMQ does not support async operation with Trio. Also, ZeroMQ forces the use of the asyncio.WindowsSelectorEventLoopPolicy
event loop.
One way to reduce the jitter is to schedule the task early and busy loop on short synchronous sleeps till the polling deadline, but it is a big ugly and wasteful.
Where can I look for a better solution?
Thank you.
Cheers,
Dan
[1] I use ctypes to call NtSetTimerResolution()
to increase clock resolution to ~1 ms. If I use regular sync calls I can easily code the polling with an interval accuracy of a couple of ms, thus I suspect that the jitter comes entirely from the timer resolution.