Blocking/Async Function Calls
Otherwise, you reinvent the Callback Hell which is JavaScript before all the async extensions.
- 
This pattern is based upon the Multi-Threaded Synchronization pattern.
 - 
An independent thread is used to run the scripting
Engine. - 
An MPSC channel (or any other appropriate synchronization primitive) is used to send function call arguments, packaged as a message, to another Rust thread that will perform the actual async calls.
 - 
Results are marshaled back to the
Enginethread via another MPSC channel. 
Implementation
See the Multi-Threaded Synchronization pattern.
- 
Spawn a thread to run the scripting
Engine. Usually thesyncfeature is NOT used for this pattern. - 
Spawn another thread (the
workerthread) that can perform the actual async calls in Rust. This thread may actually be the main thread of the program. - 
Create a pair of MPSC channels (named
commandandreplybelow) for full-duplex communications between the two threads. - 
Register async API function to the
Enginewith a closure that captures the MPSC end-points. - 
If there are more than one async function, the receive end-point on the
replychannel can simply be cloned. The send end-point on thecommandchannel can be wrapped in anArc<Mutex<Channel>>for shared access. - 
In the async function, the name of the function and call arguments are serialized into JSON (or any appropriate message format) and sent to
commandchannel, where they’ll be removed by theworkerthread and the appropriate async function called. - 
The
Engineblocks on the function call, waiting for a reply message on thereplychannel. - 
When the async function call complete on the
workerthread, the result is sent back to theEnginethread via thereplychannel. - 
After the result is obtained from the
replychannel, theEnginereturns it as the return value of the function call, ending the block and continuing evaluation.