Workers
The same heavy sum, run twice: once in the page and once on another thread. A number ticks every 60ms beside it, so you can see which of the two stops the screen.
The mailbox is not what stops it
JavaScript runs one thread. A computation that does not yield stops the page whoever wrote it — that has nothing to do with actors. Measured:
| where the 300ms of arithmetic runs | worst gap seen by another actor |
|---|---|
| this thread | 338 ms |
| a worker | 34 ms — the idle baseline |
One line says where it runs
The actor doing the work is held through an ordinary ActorRef.
a := Worker spawn: (Adder named: '集計' to: sink) on: w.
(a ask sumTo: 100000) forced printNl.
Worker spawn:on: is the only line that says where it runs. ask and tell are written the same as for an actor on this thread. A reference does not carry where its actor lives.
What may cross was settled first
Crossing a thread copies the state and every message. A block cannot be copied, because it closes over the scope it was made in.
That stops at compile time, and it names the field that caused it:
the state placed on a worker cannot cross an actor boundary: it is Job,
whose work is Block[Int -> Int], and a block closes over the scope it was
made in
Decimal, Date and Dict cross with their meaning intact. Handing them to structuredClone would strip their prototypes and a Decimal would arrive as a bare pair of numbers — money that stopped being money on the way — so the wire format is written here rather than borrowed.
Failure crosses too
Crash an actor on a worker and the watcher gets its down:, the same as on this thread.