How exactly do Lua asynchronous calls in Roblox work?
Asked Answered
E

2

5

I come from Javascript background and very used to the async calls with callbacks. Also well versed with Promise and asynch await. I recently started working on a Roblox game and its Lua SDK provides a bunch of DoSomethingAsync functions that do not expect callbacks. I looked up some resources online, people say the execution control is given up after the async call until the results come back and the control returns later. This allows the developers to write code as if things are done synchronously. Could someone verify if this is really true? Is the threading model similar to Javascript where the interpreter only ever has one single thread?

Earthnut answered 11/4, 2018 at 0:29 Comment(3)
if you want to know how something opensource exactly works look into its source code... github.com/robloxListel
Roblox isn't open source. The link you gave me is bunch of repositories that are everything but the Roblox itself.Earthnut
well sorry for that. I didn't pay close attention. if it's not opensource you can only refer to the documentation or the developers. anything else is just guess work. the API reference contains a lot on threading, coroutines. also StackOverflow is not the right place to ask these things. That's what the Robolox Communiy is for. devforum.roblox.com/c/development-supportListel
P
6

Lua, like JavaScript, only executes one thread at a time. However, Lua has a feature called coroutines that allow different threads of execution to interleave their executions. (Lua coroutines are somewhat similar to JavaScript async functions)

coroutine.resume(thread) switches the execution to thread ("It's your turn now"). The invoker of coroutine.resume will regain control when either thread finishes, or when it invokes coroutine.yield() ("I'm done for now, call me back later").

Roblox has a thread scheduler that decides which thread gets to run next when the currently scheduled thread yields. A thread will yield when it calls wait() or any yield function.

IO requests are done in a separate thread in the C++ (just like JavaScript). When the IO request finishes, the scheduler puts the yielded thread that asked for the IO at the front of the queue to be scheduled next (not unlike Javascript).


The thread scheduler link above has an example of how wait() looks, implemented in pure Lua via busy-waiting. In C++, you could use true sleeping to avoid keeping the CPU busy.

Philia answered 3/5, 2018 at 20:35 Comment(0)
I
2

It's admittedly a bit confusing because of the naming. The API calls with asynchronous in their name are asynchronous calls on the C++ side, mostly to web services, and they do use callback functions within C++. But you do not register callbacks from Lua, they behave just as if you are calling a Lua function synchronously that internally has wait() statements. These API calls are usually denoted as "YieldFunctions" on the wiki, because that's exactly what they do, they yield the Lua thread and don't return until the C++ callback function gets called and passes the results of the web request back to Lua.

Ileac answered 25/4, 2018 at 6:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.