High idle CPU usage
See original GitHub issueโ Iโm submitting a โฆ
- ๐ bug report
- ๐ฃ feature request
- โ question about the decisions made in the repository
๐ Describe the bug. What is the current behavior? The idle CPU load has been significantly increased with #199 and further multiplied with #308. The new connection manager seems to imply a loop which significantly loads the CPU, compared to before. With the second PR, the timeout has been reduced from 0.1 to 0.01, which seems to imply a 10 times increased number of loops and hence a multiplication of the CPU load. Now #311 addressed the regression of #199 in a better way, making the reduced timeout obsolete, as far as I understand. I just tried changing the 0.01 here back to 0.1, basically reverting #308, and indeed the CPU load goes back again to match moreless the state of #199 or even lower.
โ What is the motivation / use case for changing the behavior? The absolute CPU load may be small, but especially on smaller SBCs this is quite an issue. So to keep cheroot/CherryPy a great HTTP server for embedded devices, it would be great to reduce idle CPU usage to a minimum. For reference: https://github.com/HTPC-Manager/HTPC-Manager/issues/30
๐ก To Reproduce
Steps to reproduce the behavior:
git clone https://github.com/HTPC-Manager/HTPC-Manager.git
cd HTPC-Manager
git checkout MichaIng-CherryPy
pip3 install -Ur requirements.txt
python3 Htpc.py
# Check CPU usage of that process
pip3 install -U cherrypy
python3 Htpc.py
# Check and compare CPU usage
pip3 install -U 'cheroot==8.0.0'
python3 Htpc.py
# Check and compare CPU usage
pip3 install -U 'cheroot==8.10'
python3 Htpc.py
# Check and compare CPU usage
pip3 install -U 'cheroot==8.4.2'
python3 Htpc.py
# Check and compare CPU usage
pip3 install -U 'cheroot'
# Adjust below path according to Python version
sed -i 's/timeout=0\.01/timeout=0\.1/' /usr/local/lib/python3.9/dist-packages/cheroot/connections.py
python3 Htpc.py
# Check and compare CPU usage
๐ก Expected behavior
I expect a minimal CPU usage when the HTTP server is not accessed at all.
๐ Details
No logs, I basically did it via htop -d 10
. Not a very precise tool for measuring process CPU usage, but the differences are very significant when counting the seconds in which the CPU time in centiseconds raises.
๐ Environment
- Cheroot version: 8.5.2 and others (see above)
- CherryPy version: 18.6.1
- Python version: 3.9.2 and others
- OS: Debian Bullseye and others
- Browser: not applicable
๐ Additional context
There are no errors involved, just the connection manager itself checking for idle connections (as far as I understood) very often, which implies CPU usage.
Issue Analytics
- State:
- Created 2 years ago
- Comments:14 (14 by maintainers)
Top GitHub Comments
Thatโs alright. Now we wait ๐ Iโd accept a PR but Iโd like to get more feedback first because previous refactoring attempts caused regressions which Iโd like to avoid (also, Iโm not sure if we can come up with proper regression tests for the CI to catch problems in the future).
This has now been merged here: https://github.com/cherrypy/cheroot/pull/401 Testing/verifying the idle CPU usage benefits would be welcome.
On Windows systems, sadly a capped timeout needs to stay, as the connection handler
select()
function somehow on Windows does not return as fast as a connection is detected. The timeout however has been increased from0.01
to0.05
seconds, which seems to be a good balance between idle CPU usage and max delay for processing an incoming connection. For Raspberry Pi with Linux however this doesnโt play a role sinceselect()
returns immediately once incoming connections appear. Thatexpiration_interval
(defaulting to0.5
seconds) needs to be kept as well on Linux is to assure that expired connections are disconnected and removed in time, since new connections and expiry are done within the same loop.