Skip to content

WorkerComm API

phoenixide edited this page Mar 14, 2024 · 2 revisions

worker/WorkerComm

WorkerComm provides util methods to communicate between web workers and Phoenix. This module can be loaded from within web-workers and a phoenix extension that loads the web-worker.

Import

Creating a WebWorker from your extension and attaching WorkerComm to it.

See an example extension code below that creates its own web worker and uses WorkerComm for communication.

// from within an extension
const WorkerComm = brackets.getModule("worker/WorkerComm"),
      EventDispatcher = brackets.getModule("utils/EventDispatcher"),
      ExtensionUtils = brackets.getModule("utils/ExtensionUtils");

// figure out the path of the web worker relative to your extension
let workerPath = ExtensionUtils.getModulePath(module, "my_worker_path_within_extension.js")

// we need to pass in the `workerCommUrl` so that the web-worker can
// load`WorkerComm` within the worker context as described below.
let workerCommUrl = `${Phoenix.baseURL}worker/WorkerComm.js`;
let eventDispatcherURL = `${Phoenix.baseURL}utils/EventDispatcher.js`;

// load the worker
const _myWorker = new Worker(
`${workerPath}?workerCommUrl=${workerCommUrl}&eventDispatcherURL=${eventDispatcherURL}`);

// Not create a `WorkerComm` object and attach to your extension module exports.
EventDispatcher.makeEventDispatcher(exports);
// all WorkerComm objects needs to be an EventDispatcher.
WorkerComm.createWorkerComm(_myWorker, exports);

// Now `exports` can be used to communicate with the web-worker
// using `WorkerComm` APIs listed below.

Loading WorkerComm from within your webWorker

The Web Worker we created above also needs to load WorkerComm to be able to communicate with the WorkerComm instance in Phoenix. For this, we need to load WorkerComm from the URL parameters. (WorkerComm.js lib url needs to passed in while creating the web worker from Phoenix).

const urlParams = new URLSearchParams(location.search);
importScripts(urlParams.get('workerCommUrl'));
importScripts(urlParams.get('eventDispatcherURL'));
// After this, a global `WorkerComm` object will be available within the
// web-worker that can be used to communicate with Phoenix.

APIs

createWorkerComm

Adds support for WorkerComm APIs to the provided web-Worker instance. Only available in the main thread. This API should be called immediately after creating the worker in main thread.

Type: function

Parameters

  • postTarget string The web-worker reference.
  • eventDispatcher object created with util/EventDispatcher.

Examples

Create a web-worker with WorkerComm in an extension.

// load the worker [See API docs for full sample]
const _myWorker = new Worker(
`${workerPath}?workerCommUrl=${workerCommUrl}&eventDispatcherURL=${eventDispatcherURL}`);

// Now create a `WorkerComm` object and attach to your extension module exports.
EventDispatcher.makeEventDispatcher(exports);
// all WorkerComm objects needs to be an EventDispatcher.
WorkerComm.createWorkerComm(_myWorker, exports);

setExecHandler

Sets a named function execution handler in the main thread or worker thread.

Type: function

Parameters

  • fnName string The name of the function to register as exec handler.
  • execHandlerFn function

Examples

To set a named function sayHello in worker and phoenix

function sayHello(arg)=>{
    console.log("hello from worker ", arg); // prints "hello from worker phoenix"
    return "Hello Phoenix";
}

// For usage in web-worker say my_worker.js, use the global `WorkerComm` object.
WorkerComm.setExecHandler("sayHello", sayHello);
// For usage in phoenix extension side, use `eventDispatcher` object used with `createWorkerComm`.
YourWorker.setExecHandler("sayHello", sayHello);

Returns Promise That will be resolved or rejected based on function execution at the other end.

execPeer

Executes the named function at the other end if present. If this is called from the main thread, it will execute the function at the worker thread and vice-versa. The function to execute is set with API setExecHandler.

Type: function

Parameters

  • fnName string The name of the function to execute at the other end.
  • paramObject object to be passed on to the function at the other end.

Examples

To Execute a named function sayHello in the worker from phoenix

// in my_worker.js
WorkerComm.setExecHandler("sayHello", (arg)=>{
    console.log("hello from worker ", arg); // prints "hello from worker phoenix"
    return "Hello Phoenix";
  });
// In Phoenix/extension
let workerMessage = await YourWorker.execPeer("sayHello", "phoenix");
console.log(workerMessage); // prints "Hello Phoenix"

Returns Promise That will be resolved or rejected based on function execution at the other end.

triggerPeer

Triggers events at the other end on the eventDispatcher. If this is called from the main thread, it will trigger WorkerComm global at the worker thread. If this is called from the worker thread, it will trigger eventDispatcher used in createWorkerComm API call when creating the worker.

Type: function

Parameters

  • eventName string to trigger at the other end
  • paramObject object to be passed on to the event listener at the other end.

Examples

To Trigger a named event searchDone from worker to phoenix

// in my_worker.js
WorkerComm.triggerPeer("searchDone", {matches: 2});

// In Phoenix/extension, you can listen to these events
YourWorker.on("searchDone", (result)=>{
    console.log(result.matches);
});

loadScriptInWorker

Loads a script into the worker context. Only available within the main thread. This can be used by the main Phoenix thread to dynamically load scripts in the worker-thread.

Type: function

Parameters

  • scriptURL string the Full url to load.
  • isModule boolean if the url is a module url

Examples

To load a script add_worker_Script.js into the your worker:

WorkerComm.createWorkerComm(_myWorker, exports);
.....
let ExtensionUtils = brackets.getModule("utils/ExtensionUtils");
let addWorkerScriptPath = ExtensionUtils.getModulePath(module, "add_worker_Script.js")
await exports.loadScriptInWorker(addWorkerScriptPath);
// if the worker is an es-module, then set optional isModule to true
// Eg.loadScriptInWorker(addWorkerScriptPath, true);

EVENT_WORKER_COMM_INIT_COMPLETE

Raised on main thread when WorkerComm is loaded in the web-worker and is ready.