Skip to content

Thread pool's event APIs shouldn't be used to distribute work #128

Open
@davisjam

Description

@davisjam

I'm trying to learn this module, and it's giving me some trouble. The thread pool doesn't seem to behave as I expect.

I'm working on a tweaked version of examples/quickIntro_multiThreadEvented.js as follows:

//Emit a bunch of 'giveMeTheFibo' requests
for (var i = 0; i < 100; i++)
  threadPool.any.emit('giveMeTheFibo', 30);

//Listener for the 'theFiboIs' events emitted by the child/background thread.
threadPool.on('theFiboIs', function cb (data) {
  process.stdout.write(" ["+ this.id+ "]"+ data);
});

There's still a threadpool of size 10.

When I run this, there's a noticeable pause, and then all of the requests are completed at once. In addition, they all complete on the same thread.

$ node quickIntro_multiThreadEvented_DAVISJAM.js
 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269

I tweaked the spinForever function to print statistics every so often.

$ node quickIntro_multiThreadEvented_DAVISJAM.js
spinForever: totalThreads 10 pendingJobs 0 idleThreads 10
spinForever: totalThreads 10 pendingJobs 0 idleThreads 10
spinForever: totalThreads 10 pendingJobs 0 idleThreads 10
spinForever: totalThreads 10 pendingJobs 0 idleThreads 10
spinForever: totalThreads 10 pendingJobs 0 idleThreads 10
spinForever: totalThreads 10 pendingJobs 0 idleThreads 10
spinForever: totalThreads 10 pendingJobs 0 idleThreads 10
spinForever: totalThreads 10 pendingJobs 0 idleThreads 10
 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269 [0]1346269spinForever: totalThreads 10 pendingJobs 0 idleThreads 10
spinForever: totalThreads 10 pendingJobs 0 idleThreads 10
spinForever: totalThreads 10 pendingJobs 0 idleThreads 10

This seems to suggest the following sequence when I run my program:

  1. I queue 100 expensive events
  2. They all get emitted to thread 0
  3. Each time thread 0 completes an event, it emits an event to itself (going at the end of its event queue)
  4. Once the 100 expensive events finish, thread 0 handles all of the pending cleanup events

Step 3 is indeed suggested by the code of quickInto_evented_childThreadCode.js:

thread.on('giveMeTheFibo', function onGiveMeTheFibo (data) {
  this.emit('theFiboIs', fibo(+data)); //Emits 'theFiboIs' in the parent/main thread.
  ^^^^                                 ^^^^^^^^^^^^ Is this comment accurate? ^^^^^^^
});

So, here are my questions:

  1. Why isn't the work being evenly distributed across the threadpool?
  2. If I have more work pending in my threadpool than I have worker threads, and if I use the event scheme to submit requests and get responses, will my response events be artificially delayed by other pending work?

An additional, unrelated question:
3. I'm not sure how to get code from LiveScript to JavaScript to the .js.c files, so I can't tweak src/createPool.js and experiment a bit. Any hints or helpful links? I can't find anything about this online.

Regards,

Jamie

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions