Skip to content
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

TimeService rapidly falls behind actual time. #2176

Closed
greg-barnett opened this issue Aug 7, 2017 · 19 comments
Closed

TimeService rapidly falls behind actual time. #2176

greg-barnett opened this issue Aug 7, 2017 · 19 comments
Labels

Comments

@greg-barnett
Copy link

TimeService falls behind actual time by about half a second every second. It is supposed to reset every 10 minutes, but doesn't.

More details and a fix are available at:
greg-barnett@de0cc62

@asvetlov
Copy link
Member

asvetlov commented Aug 8, 2017

Hmm.
On what load you've got 50% accuracy?
I suspect it's possible only on overwhelmed event loop (or code with long blocking synchronous calls).
Also what problem it produces?
Time service is used for measuring relative slow timeouts for things like automatic socket disconnection etc. If socket will be disconnected a little later -- no problem at all!

@greg-barnett
Copy link
Author

TimeService falling behind is not load dependent.

loop_time() (which is what I'm guessing is used for timeouts) will never fall behind by more than about 1 second.

time() and strtime() will fall behind, no matter what the load is. strtime() falling behind causes Date headers in responses to be incorrect (this is how I discovered this).

See https://gist.github.com/greg-barnett/00b67d3b098bc782db642b068ad4b0d3 for a test script, and output from the master branch and my bugfix.

@socketpair
Copy link
Contributor

Sorry, it's not documented why we have TimeService either. Why not to use just time.time() ?

@asvetlov
Copy link
Member

asvetlov commented Aug 8, 2017

It is implementation detail, not part of public API.
The main idea is: formatting time for Date HTTP header is expensive operation, it might take longer than preparing and sending response.

But the header has 1 second accuracy. We could amortize formatting time by caching a string for 1 second.

@asvetlov
Copy link
Member

asvetlov commented Aug 8, 2017

Sorry, I did mislead: time service is never used for timeout calculations but for datatime formatting only.

@socketpair
Copy link
Contributor

So, caching may be implemented MUCH easier. Why not ?

_cached_time = None
_cached_time_formatted = None
def format_current_datetime():
    global _cached_time
    global _cached_time_formatted
    now = int(time.time())
    if now != _cached_time:
        _cached_time_formatted = some_format(now)
    return _cached_time_formatted

@fafhrd91
Copy link
Member

fafhrd91 commented Aug 8, 2017

+1

@greg-barnett
Copy link
Author

TimeService is also used in _process_keepalive in RequestHandler, but that should be replaceable with a call to loop.time()

@greg-barnett
Copy link
Author

This commit has a version of TimeService that only caches the formatted string for use in Date headers.
greg-barnett@eef354e

@fafhrd91
Copy link
Member

fafhrd91 commented Aug 8, 2017

if we make decision to simplify TimeService, then it should be removed at all.

@greg-barnett
Copy link
Author

This commit has slightly cleaner/faster formatting
greg-barnett@51e793d

I agree that getting rid of TimeService completely probably makes sense, but I don't know the codebase well enough to know where the functionality should reside. I don't want to add global variables if it can be avoided.

@greg-barnett
Copy link
Author

Doing some more benchmarking, I'm not even convinced that caching is required.

import time
import timeit
timeit.timeit("time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime())", number=10000)
0.016672083060257137

@fafhrd91
Copy link
Member

fafhrd91 commented Aug 8, 2017

it is, 5-7% cpu

@greg-barnett
Copy link
Author

@fafhrd91 do you have any benchmarking code that shows TimeService's caching of formatted date makes any significant performance difference? I have not been able to replicate any conditions where it has a noticeable impact.

@fafhrd91
Copy link
Member

fafhrd91 commented Aug 8, 2017

I don't have benchmarks now, but I did a lot of benchmarking when worked on performance.

@greg-barnett
Copy link
Author

#2182
Meant to associate pull request with this issue.

socketpair added a commit that referenced this issue Oct 5, 2017
@asvetlov
Copy link
Member

I hope the problem is fixed in 2.3
@greg-barnett @socketpair can we close the issue?

@greg-barnett
Copy link
Author

I'm currently on medical leave and can't devote any time to verifying the fix, so I will defer to @socketpair regarding closing this issue.

@asvetlov asvetlov closed this as completed Nov 3, 2017
@lock
Copy link

lock bot commented Oct 28, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a [new issue] for related bugs.
If you feel like there's important points made in this discussion, please include those exceprts into that [new issue].
[new issue]: https://github.com/aio-libs/aiohttp/issues/new

@lock lock bot added the outdated label Oct 28, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 28, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants