Skip to content

Commit 66437ca

Browse files
committed
Add diagrams explaining DartVM and NodeJS worker management
1 parent 7514f29 commit 66437ca

File tree

1 file changed

+60
-4
lines changed

1 file changed

+60
-4
lines changed

lib/src/embedded/README.md

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# Embedded Sass Compiler
22

33
This directory contains the Dart Sass embedded compiler. This is a special mode
4-
of the Dart Sass command-line executable, only supported on the Dart VM, in
5-
which it uses stdin and stdout to communicate with another endpoint, the
6-
"embedded host", using a protocol buffer-based protocol. See [the embedded
4+
of the Dart Sass command-line executable, only supported on the Dart VM and
5+
Node.js, in which it uses stdin and stdout to communicate with another endpoint,
6+
the "embedded host", using a protocol buffer-based protocol. See [the embedded
77
protocol specification] for details.
88

99
[the embedded protocol specification]: https://github.com/sass/sass/blob/main/spec/embedded-protocol.md
@@ -24,5 +24,61 @@ incoming messages from the embedded host:
2424

2525
[`CompilationDispatcher`]: compilation_dispatcher.dart
2626

27-
Otherwise, most of the code in this directory just wraps Dart APIs to
27+
Otherwise, most of the code in this directory just wraps Dart APIs or JS APIs to
2828
communicate with their protocol buffer equivalents.
29+
30+
## Worker Communication and Management
31+
32+
The way Dart VM launches lightweight isolates versus Node.js launches worker
33+
threads are very different.
34+
35+
In Dart VM, the lightweight isolates shares program structures like loaded
36+
libraries, classes, functions, etc., even including JIT optimized code. This
37+
allows main isolate to spawn child isolate with a reference to the entry point
38+
function.
39+
40+
```
41+
┌─────────────────┐ ┌─────────────────┐
42+
│ Main Isolate │ Isolate.spawn(workerEntryPoint, mailbox, sendPort) │ Worker Isolate │
43+
│ ├───────────────────────────────────────────────────►│ │
44+
│ │ │ │
45+
│ ┌─────────────┐ │ Synchronous Messaging │ ┌─────────────┐ │
46+
│ │ Mailbox ├─┼────────────────────────────────────────────────────┼►│ Mailbox │ │
47+
│ └─────────────┘ │ │ └─────────────┘ │
48+
│ │ │ │
49+
│ ┌─────────────┐ │ Asynchronous Messaging │ ┌─────────────┐ │
50+
│ │ ReceivePort │◄┼────────────────────────────────────────────────────┼─┤ SendPort │ │
51+
│ └─────────────┘ │ │ └─────────────┘ │
52+
│ │ │ │
53+
└─────────────────┘ └─────────────────┘
54+
```
55+
56+
In Node.JS, the worker threads do not share program structures. In order to
57+
launch a worker thread, it needs an entry point file, with the entry point
58+
function effectly hard-coded in the entry point file. While it's possible
59+
to have a separate entry point file for the worker threads, it's requires more
60+
complex packaging changes with `cli_pkg`, therefore the main thread the worker
61+
threads shares [the same entry point file](js/executable.dart), and the entry
62+
point file will decide what to run depends on `worker_threads.isMainThread`.
63+
64+
```
65+
if (worker_threads.isMainThread) { if (worker_threads.isMainThread) {
66+
mainEntryPoint(); mainEntryPoint();
67+
} else { } else {
68+
workerEntryPoint(); new Worker(process.argv[1], { workerEntryPoint();
69+
} argv: process.argv.slice(2), }
70+
workerData: channel.port2,
71+
┌────────────────────────────────────┐ transferList: [channel.port2] ┌────────────────────────────────────┐
72+
│ Main Thread │ }) │ Worker Thread │
73+
│ ├────────────────────────────────────────────────────────────►│ │
74+
│ │ │ │
75+
│ ┌────────────────────────────────┐ │ Synchronous Messaging │ ┌────────────────────────────────┐ │
76+
│ │ SyncMessagePort(channel.port1) ├─┼─────────────────────────────────────────────────────────────┼►│ SyncMessagePort(channel.port2) │ │
77+
│ └────────────────────────────────┘ │ │ └────────────────────────────────┘ │
78+
│ │ │ │
79+
│ ┌────────────────────────────────┐ │ Asynchronous Messaging │ ┌────────────────────┐ │
80+
│ │ channel.port1 │◄┼─────────────────────────────────────────────────────────────┼─┤ channel.port2 │ │
81+
│ └────────────────────────────────┘ │ │ └────────────────────┘ │
82+
│ │ │ │
83+
└────────────────────────────────────┘ └────────────────────────────────────┘
84+
```

0 commit comments

Comments
 (0)