Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
841 views
in Technique[技术] by (71.8m points)

node.js - Is nodejs representing Reactor or Proactor design pattern?

Many articles online demonstrates nodejs as an example of reactor pattern. Isn't it rather proactor?

As far as I understand, the difference between the two is:

  1. reactor handles events in a single thread (synchronously),
  2. proactor handles events is multiple threads (asynchronously) with completion callbacks.

For example in this article:

Reactor Pattern is an idea of non-blocking I/O operations in Node.js. This pattern provides a handler(in case of Node.js, a callback function) that is associated with each I/O operation. When an I/O request is generated, it is submitted to a demultiplexer.

Isn't it actually definition of proactor?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I wasn't familiar with the Proactor design pattern. After reading a bit about it I think I understand your confusion.

Many articles online demonstrates nodejs as an example of reactor pattern

This is true.

Isn't it actually definition of proactor?

This is also true.

The difference is your point of view.

Internally, node's event loop is a blocking call (ironically). That's just the most efficient way to use non-blocking I/O. Different OSes have different functions to request the OS to wake your process up if something you are interested in happens. Due to POSIX requirements there is a cross-platform API that all modern OSes support: select(). Node.js actually uses libuv which automatically picks the right API at compile time depending on the target platform. But for the purposes of this answer we're going to focus on select(). So lets look at select():

    numberOfEvents = select(numberOfWaits, read, write, err, timeout);

The select() function blocks for up to timeout milliseconds or something happens to either the read, write or err files/sockets. With just a single function the OS provides enough functionality to implement most of node.js from timers like setTimeout() and setInterval() to listening to network sockets. Using select() the event loop looks something like this:

// Pseudocode:

while(1) {
    evaluateJavascript();
    timeout = calculateTimers();
    events = select(n, read, write, err, timeout);
    if (events > 0 || timersActive()) {
        getCallbacks(events, read, write, err, timers());
    }
}

This is basically a Reactor design pattern.

However, node hides this away in its implementation. What it exposes to Javascript programmers is a set of APIs that registers callbacks and calls those callbacks when an event happens. This is partly historical (the browser APIs was designed that way) and partly practical (it's a much more flexible architecture - almost all GUI frameworks from GTK to wxWindows to .Net works this way).

You may recognise that this sounds a lot like a Proactor design pattern. And in fact it is.

So node.js itself is an example of Reactor design pattern.

Javascript programs written in node.js are examples of Proactor design pattern.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...