Workers
Workers API
WLJS provides asynchronous access to parallel Wolfram kernels. The freeware Wolfram Engine is not limited to a single parallel kernel or subkernel, so this API can be used to build truly parallel Wolfram Language workflows.
Why not
ParallelSubmit?
The default Wolfram parallel API is blocking, which makes it hard to stream data in and out without pausing the main kernel. The Workers API avoids that bottleneck by using EventHandler and EventFire as a bidirectional message channel.
Each worker runs in an isolated Wolfram subkernel and communicates with the main kernel through a shared-memory WSTP link. The design mirrors JavaScript Workers: launch a worker, subscribe to messages from it, post messages to it, and terminate it when it is no longer needed.
Inside the worker, use EventHandler[Null, ...] to receive messages from the main kernel and EventFire[Null, ...] to send messages back.
WorkerLaunch
Launches a new worker from a held expression or from a Wolfram Language source file.
WorkerLaunch[expr_] _WorkerObject
WorkerLaunch[path_String] _WorkerObject
WorkerLaunch[file_File] _WorkerObjectWorkerLaunch has the HoldFirst attribute. The expression is transferred to a fresh subkernel after the worker event bridge is installed.
Workers are isolated. Definitions from the main kernel are not shared automatically, so a worker expression should be self-contained or should load the packages and files it needs.
Message loopback
A minimal worker can listen for any message and send it back to the main kernel.
w = WorkerLaunch[Module[{},
EventHandler[Null, {
_ -> (EventFire[Null, #]&)
}]
]]Subscribe to messages from the worker, then submit a message to it:
EventHandler[w, Print];
EventFire[w, "Hey!"];The worker receives "Hey!" through EventHandler[Null, ...] and replies with EventFire[Null, "Hey!"].
Launching from a file
You can also start a worker from a .wl file:
w = WorkerLaunch["path_to_worker.wl"];or with a File object:
w = WorkerLaunch[File["path_to_worker.wl"]];The file is imported as Wolfram Language source and evaluated inside the worker.
Topics
EventFire supports the same topic based pattern as other WLJS event objects.
w = WorkerLaunch[
EventHandler[Null, {
"Square" -> Function[x,
EventFire[Null, "Result", x^2]
],
_ -> Function[data,
EventFire[Null, "Error", data]
]
}]
];
EventHandler[w, {
"Result" -> Print,
"Error" -> Echo
}];
EventFire[w, "Square", 12];When no topic is provided, "Message" is used as the default topic.
EventFire[w, data]is equivalent to sending the worker a "Message" event.
WorkerObject
WorkerLaunch returns a WorkerObject, which behaves like an event object in the main kernel.
EventHandler[w_WorkerObject, handler_]
EventHandler[w_WorkerObject, {handlers___Rule | handlers___RuleDelayed}]
EventFire[w_WorkerObject, data_]
EventFire[w_WorkerObject, topic_, data_]The worker-side equivalents use Null:
EventHandler[Null, handler_]
EventHandler[Null, {handlers___Rule | handlers___RuleDelayed}]
EventFire[Null, data_]
EventFire[Null, topic_, data_]You can also clone and remove worker handlers using the normal event helpers:
EventClone[w_WorkerObject] _EventObject
EventRemove[w_WorkerObject]
EventRemove[w_WorkerObject, pattern_]Workers
Returns the current pool of active worker objects.
Workers[] _ListThis is useful for inspection or for closing all workers during cleanup:
WorkerClose /@ Workers[];WorkerReadyQ
Checks whether a worker link is still valid.
WorkerReadyQ[w_WorkerObject] _BooleanFor example:
If[WorkerReadyQ[w],
EventFire[w, "Message", "ping"]
]WorkerClose
Terminates the worker and removes the event handlers connected to it.
WorkerClose[w_WorkerObject]Close workers explicitly when they are no longer needed:
WorkerClose[w]For long-running workflows, send a final event from the worker before closing it, then close the worker from the main kernel after receiving that event.