godotengine/godot

High CPU usage on HTTPClient with threads (on slow server response)

AlexHolly opened this issue · 5 comments

Godot version:
0ab0d11

OS/device including version:
Tested on Windows 10 and x11(Mint)

Issue description:
Maybe related to #32807
Using Theads to run HTTPClient Requests in the background is using 13-40% CPU (Reason is probably a while/requesting data from socket all the time instead of blocking until data is actually available)

I added a variable which reduces the CPU to ~ 0 - 5%
Currently it is always false.

return read(p_buffer, p_bytes, r_received, false);

Steps to reproduce:
Run example project
Check Taskmanager CPU usage or listen to your CPU fan :D

Minimal reproduction project:
http-bug.zip

Let me know if you think it is a bug I will open a PR with my solution.

This line should block until data comes in.

err = connection->get_partial_data(p_buffer + r_received, left, read);

Solution:
err = connection->get_partial_data(p_buffer + r_received, left, read, true);

I think I understand the problem, and this is probably a defect introduced in #21976 .
We can't block in get_partial_data (which is supposed to be non-blocking).
get_data should be used instead, but due to the current API, we can't use that there either:

if (blocking) {
// We can't use StreamPeer.get_data, since when reaching EOF we will get an
// error without knowing how many bytes we received.
Error err = ERR_FILE_EOF;
int read = 0;

A proper fix might be possible without breaking the upper API nor reintroducing the EOF read bug, but this needs further investigation.

@AlexHolly can you try out #33785 and and let us know if it fixes your issue?

It solves my case.

Do you have an idea why downloading a file still needs so much CPU?
#32807
Tested it with HTTPClient and HTTPRequest

Seems somewhat still valid in 3.2.3
The CPU usage is high (20%), but then goes down to standard ~2%.

I need to salvage #33785 to fix this.