Purpose of OS.delay_msec

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Drilliak

I’m new on Godot engine and I’m working on a simple project where I need to perform some HTTP calls.

I have read the HTTPClient class documentation and I don’t understand why the thread is stopped during http polling.

while http.get_status() == HTTPClient.STATUS_REQUESTING:
    http.poll()
    print("Requesting...")
    if not OS.has_feature("web"):
        OS.delay_msec(500) # here
    else:
        yield(Engine.get_main_loop(), "idle_frame")

and

        while http.get_status() == HTTPClient.STATUS_BODY:
        http.poll()
        var chunk = http.read_response_body_chunk() # Get a chunk.
        if chunk.size() == 0:
            OS.delay_usec(1000) # here
        else:
            rb = rb + chunk

    # Done!

You can find the full example here

These sleep lines slow down the request. I tried to remove these lines and it seems to work. Can I remove them safely or am I missing something ?

I know there is a high level HTTPRequest class but I need more control (I don’t want to use the signal design with the HTTPRequest class). Anyway, I would like to understand this polling mechanism.

    if not OS.has_feature("web"):
        OS.delay_msec(500) # here

I don’t quite understand what OS.has_feature("web") means… if it means “can this build of Godot do web things?” then there is no point making a request in the first place.

In the second snippet I think it’s there just to give time for the thread to breathe and get more data from the web. If you remove it you’ll basically max out CPU for no good reason. I wonder why yield wasn’t used there. The whole thing doesnt need to be in a while loop either, it could be in a _process since it’s polling.

Zylann | 2019-12-10 13:49

Thanks for your answer!

According to the documentation, OS.has_feature("web") returns true if the game is running in a web browser. So in my mobile game case, the OS.delay_msec(500) is always executed and the request is pretty slow (waiting 500ms between 2 poll calls). I don’t understand why I can’t use yield(Engine.get_main_loop(), "idle_frame") in all cases.

In the second snipped, how can OS.delay_usec give time for the thread to get more date if the thread is sleeping ? Is there an other thread filling a shared buffer ?

Anyway, I think I will follow your suggestion and move this polling part in the _process function.

That brings me to an other question: if I use the _process function, will I be able to make two requests with the same object at the same time or should I declare two instances to make concurrent request ?

Drilliak | 2019-12-10 18:31

In the second snippet you don’t want the CPU to be maxed (which consumes power), so sleeping a little gives time for the computer to do other things. It won’t slow down the request, unless you sleep too much maybe.

You are free to poll wherever you want (most likely regularly until it’s done). I never used HTTPClient before, but I’ve tried HTTPrequest and I think for the latter you’d need two if you want them to run at the same time (however how would you know which answer is from which request).

Zylann | 2019-12-10 18:40

Ok thank you !

I think polling in the _process function is the best option. I’ll try that :slight_smile:

Drilliak | 2019-12-10 20:30