|
2 | 2 |
|
3 | 3 | Example of spawning a Rust async task on the [tokio][tokio] thread pool and resolving a JavaScript [Promise][promise] after it completes. |
4 | 4 |
|
5 | | -_**Note:** This example uses a pre-release version of Neon._ |
6 | | - |
7 | 5 | [tokio]: https://tokio.rs |
8 | 6 | [promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise |
9 | 7 |
|
10 | 8 | ## Methods |
11 | 9 |
|
12 | | -#### `function nodeReleaseDate(): Promise<string>` |
13 | | - |
14 | | -Asynchronously fetch the release date for the currently running Node process from nodejs.org. |
15 | | - |
16 | | -## Design |
17 | | - |
18 | | -### Executor |
19 | | - |
20 | | -For optimum task scheduling, it is best to have a single Rust task executor (e.g., tokio runtime). To make the runtime singleton available to Neon functions, it is stored in a global using `OnceCell`. |
21 | | - |
22 | | -```rust |
23 | | -use once_cell::sync::OnceCell; |
24 | | -use tokio::runtime::Runtime; |
25 | | - |
26 | | -static RUNTIME: OnceCell<Runtime> = OnceCell::new(); |
27 | | -``` |
| 10 | +### `function nodeReleaseDate(version: string): Promise<string>` |
28 | 11 |
|
29 | | -A small helper is provided to lazily initialize the runtime and throw an exception on failure. |
| 12 | +Asynchronously fetch the release date for a given Node release from nodejs.org. |
30 | 13 |
|
31 | | -```rust |
32 | | -fn runtime<'a, C: Context<'a>>(cx: &mut C) -> NeonResult<&'static Runtime> { |
33 | | - RUNTIME.get_or_try_init(|| Runtime::new().or_else(|err| cx.throw_error(err.to_string()))) |
34 | | -} |
35 | | -``` |
| 14 | +`nodeReleaseDate` is a Rust `async fn`. The argument uses [`TryFromJs`][tryfromjs] and return value uses [`TryIntoJs`][tryintojs] for ergonomic conversions. |
36 | 15 |
|
37 | | -### Spawning Tasks |
| 16 | +### `function currentNodeReleaseDate(): Promise<string>` |
38 | 17 |
|
39 | | -Tasks may be spawned on the tokio runtime by using the `RUNTIME` handle. Spawning a task does *not* block the current thread. Inside a task the `await` keyword may be used and typical async Rust patterns may be used. |
40 | | - |
41 | | -```rust |
42 | | -let rt = runtime(&mut cx)?; |
43 | | - |
44 | | -rt.spawn(async move { |
45 | | - // Asynchronous Rust may used in here |
46 | | -}); |
47 | | -``` |
48 | | - |
49 | | -### Promises |
50 | | - |
51 | | -When a task is spawned on the tokio runtime, it will be executed at a later time. JavaScript needs to be notified when the task completes. |
52 | | - |
53 | | -* Neon [`Channel`][channel] may be created for moving an operation from the tokio thread pool back to the JavaScript main thread. |
54 | | -* [`cx.promise()`][cx-promise] creates a [`JsPromise`][js-promise] and [`Deferred`][deferred] for signaling JavaScript. |
55 | | -* [`JsPromise`][js-promise] is synchronously returned and may be used with `await` in JavaScript |
56 | | -* [`Deferred`][deferred] is used to settle the [`JsPromise`][js-promise] from the [`Channel`][channel] callback. |
57 | | - |
58 | | -```rust |
59 | | -let channel = cx.channel(); |
60 | | -let (deferred, promise) = cx.promise(); |
61 | | - |
62 | | -rt.spawn(async move { |
63 | | - // Code here executes non-blocking on the tokio thread pool |
| 18 | +Asynchronously fetch the release date for the currently running Node process from nodejs.org. |
64 | 19 |
|
65 | | - deferred.settle_with(&channel, move |mut cx| { |
66 | | - // Code here executes blocking on the JavaScript main thread |
| 20 | +`currentNodeReleaseDate` needs to access the JavaScript VM synchronously in order to get the current Node version before spawning an async tokio task. |
67 | 21 |
|
68 | | - Ok(cx.undefined()) |
69 | | - }); |
70 | | -}); |
| 22 | +Writing a _synchronous_ Rust `fn`, that returns a Rust future, allows synchronous setup code that uses [`Cx`][cx]. |
71 | 23 |
|
72 | | -Ok(promise) |
73 | | -``` |
| 24 | +**Note**: The returned future is still required to be `Send + 'static`. |
74 | 25 |
|
75 | | -[channel]: https://docs.rs/neon/0.10.0-alpha.3/neon/event/struct.Channel.html |
76 | | -[cx-promise]: https://docs.rs/neon/0.10.0-alpha.3/neon/context/trait.Context.html#method.promise |
77 | | -[js-promise]: https://docs.rs/neon/0.10.0-alpha.3/neon/types/struct.JsPromise.html |
78 | | -[deferred]: https://docs.rs/neon/0.10.0-alpha.3/neon/types/struct.Deferred.html |
| 26 | +[tryfromjs]: https://docs.rs/neon/latest/neon/types/extract/trait.TryFromJs.html |
| 27 | +[tryintojs]: https://docs.rs/neon/latest/neon/types/extract/trait.TryIntoJs.html |
| 28 | +[cx]: https://docs.rs/neon/latest/neon/context/struct.Cx.html |
0 commit comments