Worker

同じ重い集計を二回実行する画面です。一回目はメインスレッド、二回目は Worker で実行します。横で 60ms ごとに数字が更新されており、どちらのときに画面が止まるかを見られます。

計測

JavaScript のスレッドは一本です。同期で回る重い計算は、書き方に関わらず画面を止めます。アクタの仕組みとは関係ありません。

300ms の計算の実行場所他のアクタが止められた最大時間
メインスレッド338 ms
Worker34 ms(アイドル時と同じ)

スレッドの指定

Worker で動かすアクタも、通常の ActorRef で参照します。

a := Worker spawn: (Adder named: '集計' to: sink) on: w.

(a ask sumTo: 100000) forced printNl.

スレッドを指定しているのは Worker spawn:on: の一行だけです。ask も tell も、同じスレッドの場合と同じ書き方です。ActorRef はアクタがどのスレッドで動いているかを持ちません。

スレッドを跨げない値

スレッドを跨ぐとき、状態もメッセージもコピーされます。ブロックは作られた場所の変数を参照しているのでコピーできず、渡せません。ブロックを持つ状態を Worker に置こうとすると、原因の項目を示してコンパイルエラーになります。

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、Dict は型を保ったまま渡ります。ブラウザの structuredClone はクラス情報を失うので、スレッド間の受け渡し形式は LPScript のランタイムが持っています。

エラー時の動作

Worker で動くアクタがエラーで止まると、監視しているアクタに down: が届きます。同じスレッドの場合と同じです。