rscarson / rustyscript

Effortless JS integration for rust
MIT License
98 stars 10 forks source link

WIP: `AsyncRuntime` and `AsyncWorker` #143

Open krhougs opened 1 week ago

krhougs commented 1 week ago

Problems to solve

To-do

rscarson commented 1 week ago

Thanks for the contribution!

You are correct that creating a new tokio runtime each time is a waste, that's actually fixed in master as of now

What's the advantage of a seperate runtime over the async variants of the existing functions?

krhougs commented 1 week ago

Hi, @rscarson!

What's the advantage of a seperate runtime over the async variants of the existing functions?

Current Runtime with sync API provides an easy way to run any JS async functions in sync programs, it blocks current thread on every operation on the deno runtime until finished or timed out. While it is quite simple and elegant when the program is tiny or the JS code doesn't play too much with IO, it brings limitations:

To solve the problems above:

rscarson commented 1 week ago

Hi, @rscarson!

What's the advantage of a seperate runtime over the async variants of the existing functions?

Current Runtime with sync API provides an easy way to run any JS async functions in sync programs, it blocks current thread on every operation on the deno runtime until finished or timed out. While it is quite simple and elegant when the program is tiny or the JS code doesn't play too much with IO, it brings limitations:

  • The Runtime will always panic if the caller function is already running on a tokio runtime (Worker solves this but there are still problems)
  • On common circumstances, the whole program will block to wait for js calls if the calls take too long to finish(even with Worker)
  • It's impossible to exchange data and send events between rust code and current running js code
    • Example 1: I'd like to run a JS function to provide background IPC
    • Example 2: I'd like to run a JS function polling for external states and reporting the states to rust code

To solve the problems above:

  • AsyncRuntime provides non-blocking APIs that directly works within a tokio CurrentThread runtime (JsRuntime from deno_core is not thread-safe, it panics in tokio MultiThreaded runtimes if you are trying to invoke any Rust closures(e.g. deno_fetch) in JS codes)
  • AsyncWorker wraps the AsyncRuntime with a dedicated thread and a dedicated tokio CurrentThread runtime, and provides non-blocking APIs for complex applications running with an existing tokio MultiThreaded runtime.

I mean compared to the WIP Async API already present in master

The upcoming 0.5.0 release will have full async support on the existing runtime, and reuse its tokio runtime