-
Notifications
You must be signed in to change notification settings - Fork 2k
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
[no squash] Get rid of the last remaining sync. HTTP requests on the main thread #14649
base: master
Are you sure you want to change the base?
Conversation
end | ||
if package.raw_deps then | ||
return package.raw_deps | ||
local function make_callback_coroutine(fn, callback) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be interesting to add a coroutine http api
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented in 066e07c to give the idea a try.
Differences:
core.parse_json
runs on the main thread again. Previously, this PR moved it intocore.handle_async
.- The difference between the master branch and this PR is smaller than before.
- The overall amount of code is still exactly the same.
- Is this approach more ergonomic? I don't know.
What do you think?
EDIT: I've come to the conclusion that I don't like it, also because I noticed that the old version can be made even shorter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I just don't understand this resumer-pattern, but would await
(like here) be a suitable replacement?
Just a suggestion ofc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When using your await function, the problem I have is that the final callback (the one passed into contentdb.has_hard_deps
/ contentdb.resolve_dependencies
by the API user) is not called. To make this work, the value returned by coroutine.resume
here
coroutine.resume(co, ...) |
would somehow have to get back to the final callback, which brings me back to my "resumer" pattern.
This is my first time working with coroutines. There might of course be a better approach that I haven't seen.
b13197b
to
d89cd5b
Compare
Any sync. HTTP request on the main thread is a bug, don't allow introducing one again.
d89cd5b
to
6245073
Compare
Building upon the work in #13551 and #14412, this PR aims to make sure that there will never be ANRs related to HTTP requests again.
Commit 1 moves the last remaining HTTP request from the main thread to
core.handle_async
. To reduce the amount of changes to existing code and to avoid callback hell, it uses coroutines.The HTTP request in question is the one that fetches a dependency list from CDB before attempting to install a package. While it's usually very fast, it can take long if you have a bad internet connection or if it times out.
Commit 2 removes the ability to execute synchronous HTTP requests on the main thread from
httpfetch.cpp
. This doesn't break backwards compatibility becausefetch_sync
is only available in the mainmenu. Since any synchronous HTTP request on the main thread is a bug, we should avoid introducing one again in the future.To do
This PR is a Ready for Review.
httpfetch.cpp
.There is probably more to remove, but I fear that I don't know the code well enough to avoid accidentally breaking things.
How to test
Verify that Minetest doesn't freeze for a short while anymore after you press the install button on a package.
Try to install lots of different packages from CDB. Verify that dependencies are resolved correctly and that packages are installed correctly.