0

We are executing a time taking function on web worker. Also I have a Dispatcher Class that create a single instance for other classes to use looks like below:

class Dispatcher {
constructor() {
        console.log("calling");
        this.events = {};
    }
//some code
}
const dispatcher = new Dispatcher();
export default dispatcher;

I have imported this module in another file named as DataManager Class at the top:

import dispatcher from '../../utility/dispatcher';

export class DataManager {
  notifyRenderer = (data: ResultData): void => {
        dispatcher.dispatch(NOTIFY_EVENT, data);
  }
}

and my web worker is creating a new instance of this class and from here we are triggering a notifyRenderer method written in DataManager Class.

import { DataManager } from "./data-manager";
let dm: DataManager;

addEventListener('message', (e) => {
    if (!dm) {
        dm = new DataManager();
    }

    const res = dm.addOrUpdateData(e.data.input, true);
    dm.notifyRenderer(res);
    postMessage({ type: 'Dispatch', res });
}, false);

Also I am attaching a screenshot of my console showing console.log("calling"); two times. I have no idea why Dispatch class constructor is getting called two times.

enter image description here

Is there any mistake i am doing. Need help on this please.

I feel like module imports might be the problem. Is it?

Adding screenshot trace from worker:

enter image description here

Thank you in Advance!

Dolly
  • 2,213
  • 16
  • 38
  • Your module looks fine. Are you perhaps instantiating a second worker? Importing the dispatcher in the page itself (outside the web worker)? Does the "live reloading" have something to do with it? – Bergi Aug 26 '20 at 07:56
  • Hi @Bergi Thanks for the response, Yes I am instantiating a second worker but it is in totally different component. No relations!. Second, I am importing dispatcher in other component as well. But due to mjs(require) file caching mechanism, making the constructor to called only once. But on calling a function from worker thread to main thread making the constructor calling twice. I have no idea why is that happing! i will add console.trace() screenshot in description. Have a look! – Dolly Aug 26 '20 at 09:16
  • The main thread and each worker thread all have their own instances of each module. There is no module caching across realms. You will have to instantiate one dispatcher in your app, and from other workers explicitly pass it messages. – Bergi Aug 26 '20 at 09:24
  • ohk, Is there any doc. where i can read more detail on this limitation. Secondly, how can I handle this use case then? Any Suggestions would be helpful!. As any event that i am registering on main thread dispacther object is not available in worker thread. – Dolly Aug 26 '20 at 09:27

1 Answers1

0

Everyone learns from there mistake's and practice and same happened with me here.

Everything was correct in my module's either it is Dispatcher Class, Data Manager Class and instantiate a new worker thread. The problem was that I created a single instance of Dispatcher Class at the end of that module, as I thought resulting exports will get cached(as per mjs(require) file caching mechanism,) and tried to use(import) in both main thread and worker thread and both threads was creating there own version of module instances.(My Mistake!)

I didn't even realize until bergi gave me a hint. The correct way is to send data from worker thread to main thread using postmessage and listen on main thread.

Sent from worker thread:

postMessage(dm.addOrUpdateData(e.data.input, true) as ResultData);

Listen on main thread:

this.worker.onmessage = (e: MessageEvent) => {
            if (!e.data) return;
            dispatcher.dispatch(NOTIFY_EVENT, e.data);
        };

Understand More on Realms and helping links must visit:

Thanks!

Dolly
  • 2,213
  • 16
  • 38