简体   繁体   中英

Event emitter between files not working with ES6 import/export and worker_thread

I have two files, first is state.js which you might see below:

import EventEmitter from "events";
import tasklist from 'tasklist';

export const stateManager = new EventEmitter();

//IIFE working every 10 seconds via cron task, from the file below
(async () => {
  const processes = await tasklist();
  const exist = processes.find(({imageName}) => imageName === 'process.exe');

  if (!!exist) {
    console.log(!!exist)
    stateManager.emit('state', 1);
  } else {
    console.log(!!exist)
    stateManager.emit('state', 0);
  }
})();

The second is the eventListener.js file, which running endlessly.

//import stateManager from first file
import { stateManager } from "./src/controller.js";

/**
 * Here is part of the code
 * which starts the first file
 * as a Worker cron-task every 10 seconds
 * It doesn't block the thread.
 */
const bree = new Bree({
  logger: logger,
  jobs: []
});
bree.add({
  name: "state",
  interval: ms("10s")
})
bree.start();


// First listener
console.log('check');
stateManager.on('state', function firstListener(...args) {
  console.log('State updated', args);
});

After I launch the eventListener.js , the output which I see in the console is the following:

check
false
State updated [ 0 ]
 [LOGGER]  21-03-01 18:03:67  info : Worker for job "state" online
false
 [LOGGER]  21-03-01 18:03:08  info : Worker for job "state" exited with code 0
 //every 10 second then =>
 [LOGGER]  21-03-01 18:13:69  info : Worker for job "state" online
false
 [LOGGER]  21-03-01 18:13:06  info : Worker for job "state" exited with code 0

or if I export export const stateManager = new EventEmitter() from another (third file) not the state.js directly.

check
 [LOGGER]  21-03-01 18:03:23  info : Worker for job "state" online
false
 [LOGGER]  21-03-01 18:03:63  info : Worker for job "state" exited with code 0
 //every 10 second then =>
 [LOGGER]  21-03-01 18:13:23  info : Worker for job "state" online
false
 [LOGGER]  21-03-01 18:13:63  info : Worker for job "state" exited with code 0

So the task works fine, and the event listener never ends, but somehow, it doesn't react to state event or react only once, at the begining. Why such a problem could be? Since I have no other error in the console?

If it helps, I use bree.js as a job queue manager, which actually runs the cron-task itself.

Solution

I guess I have found the solution to the problem, but I couldn't understand the reason itself.

In my case, it's better to use not the events library, but worker_threads , so the code now looks like that:

import { parentPort } from "worker_threads";
import tasklist from 'tasklist';

//IIFE working every 10 seconds via cron task, from the file below
(async () => {
  const processes = await tasklist();
  const exist = processes.find(({imageName}) => imageName === 'process.exe');
  if (parentPort) parentPort.postMessage({ state: !!exist })
})();

and the eventListener receive side looks like:

bree.on('worker created', (name) => {
  bree.workers[name].on('message', (message) => {
    console.log(message);  // Prints { state: !!exist }
  })
});

So the messages from the first file have been delivered successfully. But I'll be very glad if someone, will explain it to me, why events library can't deliver messages between different works, even if the eventListener has been exported correctly.

Bree basically starts a new process. What you got there is the equivalent of doing:

node eventListener.js

And then:

node state.js

Every 10 seconds. There's an Event Emitter being created every 10 seconds but there's no listener attached to it, because that's on your eventListener.js file which isn't being run, just state.js every 10 seconds.

Bree might be overkill for this, you could just use setInterval or a setTimeout loop. These are async anyway and you aren't doing anything heavy on the JS side so you shouldn't be blocking as much. Though if you do want to use workers, your solution seems OK to me. Might be easier to just work with workers directly and forgo Bree .

Another option would be to set up Bree with eventListener on a separate file. You just run that other file (which will run all your program every 10 seconds).

Seems I understand the reason for such behavior, but I am not sure that it's the Bree issue itself.

Just don't use the IIFE function as a build-in cron-task of Bree. Instead of that, use the cron-task inside the file. Doesn't matter how exactly you'll do it, via await sleep(time) and recursion, or via the node-scheduler module itself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM