-
Notifications
You must be signed in to change notification settings - Fork 558
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incorrect time calculation in loop.call_at() #233
Comments
I can reproduce this, even after fixing a floating-point precision issue in your demo script: - if ti > ti0:
+ if ti - ti0 > 0.0000001: Also when failing, it is always called
I think the fix would be as easy as using - when = <uint64_t>(delay * 1000)
+ when = <uint64_t>round(delay * 1000) At least it didn't report an error in 10+ minutes in my local testing. |
@fantix Yes, I think you are right. It definitely is a rounding issue. Is this the only place that time is converted from float to milliseconds integer? I guess all such places would have to be changed... |
Yes, this is the only place.
Right, that should work for now. I'll create a PR to add the |
Yeah, go for it! |
If we want this to be "no earlier than" shouldn't this be a ceil() ? |
Using round((123123.1 + 0.1) * 1000) # 123123200
math.ceil((123123.1 + 0.1) * 1000) # 123123201 But yeah, I got your point that when called with |
UVloop has a timer resolution of 1ms, so if call_at of higher than that resolution is made, uvloop may round up or down to whole milliseconds. How it does that is not so important. |
And that's probably fine, because the interval is less than the timer resolution. I think using |
Okidoki, I'll butt out ;) |
Fixed in uvloop 0.12.2. |
PYTHONASYNCIODEBUG
in env?: yesThere is a conceptual bug in the calculation of the time in call_at() here:
https://github.com/MagicStack/uvloop/blob/master/uvloop/loop.pyx#L1270
If an application calculates a time in the future to call a function with call_at(), it should be able to expect
the value of loop.time() when called inside that function to be equal or higher (later) than the timestamp that was specified. Due to timer resolution and the fact that call_at() internally does "when - self.time()" causes that this assumption is not guaranteed to be true.
The following script demonstrates this:
Eventually this script will stop after printing "ERROR!!!". This means that the timer handler mytimer() was
called a bit too early.
The text was updated successfully, but these errors were encountered: