21

I can write non-blocking I/O in Node.js very easily. It's what the entire library is set up for.

But any computation done is blocking. Any message passing over event emitters are blocking.

For example, emitting events are resolved immediately and are thus blocking:

var e = new process.EventEmitter;
e.on("foo", function() {
    console.log("event");
});
process.nextTick(function() {
    console.log("next tick");
});
setTimeout(function() {
    console.log("timeout");
}, 0);
e.emit("foo");

> event
> next tick
> timeout

Apart from wrapping calls in nextTick, how do I make code non-blocking?

I want to do as little computation per cycle of the event loop as possible, so that I can serve as many clients simultaneously as possible.

How do I write my code in a non-blocking fashion?

And when I have non-blocking code, how do I scale that across multiple processes?

One option is waiting for the WebWorker sub-process API to be finished.

3
  • 3
    Firstly, 90% of your 'Question' is not actually a question, it's more of an issue with node's Event Library, this should be brought up either as a feature request or as a possible bug on github, as for your small question I would create a question dedicated to that subject rather then squeezing it in this one. Commented Apr 14, 2011 at 22:09
  • 1
    @RobertPitt thank you for pointing out that the question was phrased poorly. i have adjusted it. I might also mention it on github. Commented Apr 14, 2011 at 22:14
  • That's a little better, thankyou. Commented Apr 14, 2011 at 22:21

2 Answers 2

9

JavaScript is single-threaded. That means that regardless of events, timeouts, or delaying with nextTick, any computation done will block the whole process.

If you split your processing in steps using process.nextTick, like it's done with setTimeout(fn, 0) on the client-side to avoid blocking the UI, you could spread your workload over a longer time span, giving some room for other functions to run.

But that's a very innefective solution - the total amount of work is the same, distributed among all cycles (making each request a little slower). In practice, any kind of computation that is expected to take more than a few milliseconds should be offloaded to a different process. To maximize concurrency you should always return to the event loop as quickly as possible.

child_process.fork() was added to v0.5 a few days ago. It simplifies child process creation and communication - not quite the web workers API, but close, see the URL https://github.com/joyent/node/blob/master/doc/api/child_process.markdown.

Sign up to request clarification or add additional context in comments.

5 Comments

That's exactly what I showed in my snippet. The event handling is blocking. My question is how do I do non blocking message passing to optimise concurrency? I guess calling process.nextTick is the best way.
@RicardoTomasi using process.nextTick is non-blocking as it allows other task to get CPU time. It's basically time splicing one CPU to make it multi threaded.
Javascript is still single threaded, and your functions will "block" regardless of their placing. The other tasks will also block, you'll be just switching their order. If you split your processing in steps, like it's done client-side to avoid blocking the UI, you can spread the same amount of work over a longer time - then you might get a little better concurrency, but in exchange for longer response times. This is not what node.js is about. The benefits of non-blocking code come from not sitting idle waiting for responses, not from avoiding all computations.
@RicardoTomasi that final comment really sums up my misconceptions. If you can edit the answer to explain my misconception I'll accept it
@Raynos edited. also added a mention to the new .fork() API, you should take a look at it.
1

There's no real multi-threading in JavaScript and that's what you need to make the call non-blocking. The only thing I can think of are web-workers: https://developer.mozilla.org/en/Using_web_workers

2 Comments

Then again, I haven't programmed in JS for several years so I might be wrong.
callbacks on process.nextTick are non-blocking. You can use an event loop to write non blocking code but the event emitters do not make use of the event loop. I don't know how to make use of the event loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.