Really nice explanation of the behavior of the node single threaded
event-loop. Much more elaborate and comprehensive than the typical 'Hello
world' explanation. Wonder if it could be included in a Node.js wiki page.

On Thu, Mar 15, 2012 at 9:04 PM, C. Mundi <[email protected]> wrote:

> This is helpful, and broadens my perspective.  Thanks for cleaning up my
> nomenclature!
> On Mar 15, 2012 3:29 AM, "Jorge" <[email protected]> wrote:
>
>> On Mar 15, 2012, at 6:53 AM, C. Mundi wrote:
>>
>> > I know *what* the following code does.  I want to understand *why*.
>> >
>> > Consider the following client/server pair:
>> >
>> > client.js
>> > var net = require('net');
>> > var conn = net.createConnection(8000, function() {  // 'connect'
>> listener
>> >   console.error('connected to server');
>> >   conn.on('data', function(data) {
>> >     var msg = data.toString();
>> >     console.error('Got data: ' + msg);
>> >     conn.write('Back at ya!');
>> >     conn.end();  // Pay close attention!
>> >   });
>> > });
>> >
>> > server.js
>> > var net = require('net');
>> > var server = net.createServer(function(client) {
>> >   console.error('Accepted connection');
>> >   client.on('end', function() {
>> >     console.error('Client has closed connection.');
>> >   });
>> >   client.on('data', function(data) {
>> >     var msg = data.toString();
>> >     console.error('Got data: ' + msg);
>> >   });
>> >   client.write('Welcome');
>> > });
>> >
>> > server.listen(8000, function() {
>> >   console.error('Listening on port 8000');
>> > });
>> >
>> > So we start the server ('node server.js') and then we run the client
>> ('node client.js') and see (as expected) that the server accepts the
>> connection from the client, they exchange a pair of messages and the client
>> exits.  Now let's comment out the 'conn.end()' from the client.  Now the
>> client hangs around until we kill it.  What I want to understand is this:
>> how does the V8 thread know that it should or should not hang around?  The
>> conn.end() is in the 'connect' event listener, which gets registered only
>> after the connection is established.  (And it is important to notice that
>> if the connection had been refused, then the client would have exited with
>> an error.)  My mental model goes like this, and I would like some feedback:
>> >
>> > During the execution of each event loop, node memoizes every async call
>> long enough to see if the callback could be called.  As long as there is at
>> least one pending callback (and no error or explicit exit() call) the event
>> loop keeps running.  Ok.  Now let's suppose the server accepts the
>> connection.  The 'connect' event is caught by the listener callback in the
>> client.  And after this 'connect' callback executes... node hangs around,
>> because the 'connect' callback registered a callback for the 'data' event.
>>  And event handlers are persistent, so execution keeps looping if the
>> conn.end() is not present.  Now, somehow, conn.end() breaks us out of the
>> loop, at which point there is nothing left to do *and* nothing left to wait
>> for, so client.js exits.  My guess is that the conn.end() call unregisters
>> all the event handlers associated with the connection object conn, at which
>> point node has nothing left to do.
>> >
>> > Am I even close to the right way of thinking about this?
>> >
>> > Thanks!
>>
>> The server (server.js): .createServer() creates a socket and then
>> .listen() puts it into listen for and accept connections mode, node notices
>> that the app is listening for connections so it must flag the event loop
>> not to quit (it's really .listen() who flags it, see below). Remove the
>> server.listen() or add a server.close() and node will remove the flag and
>> then it will quit.
>>
>> WRT the client (client.js): createConnection() creates a socket and tries
>> to connect to a host,port. Node flags the event loop not to quit until that
>> connection attempt either fails or succeeds. If the connection succeeds,
>> node will remove the flag only after the connection ends/is closed.
>>
>> For example, in the case of ev_async events, the ones that threads_a_gogo
>> (which is an über awesome module btw, check it out! :-) uses, to flag the
>> event loop not to quit yet there's an ev_ref() call:
>>
>>
>> https://github.com/xk/node-threads-a-gogo/blob/master/src/threads_a_gogo.cc#L691
>>
>> and it's thread.create() who calls it, so that node won't quit as long as
>> there's a thread alive.
>>
>> to remove the flag then I do an ev_unref() call:
>>
>>
>> https://github.com/xk/node-threads-a-gogo/blob/master/src/threads_a_gogo.cc#L358
>>
>> and I do that in thread.destroy(), for obvious reasons.
>>
>> All these ev_ref()s add up, e.g. if I .create() 3 threads and then
>> .destroy() 2 of them, there will still be one thread ev_ref()d, so the
>> event loop/node won't quit yet.
>>
>> This is how node 'learns' whether to quit or not.
>>
>> Hope it helps. Cheers,
>> --
>> Jorge.
>>
>> --
>> Job Board: http://jobs.nodejs.org/
>> Posting guidelines:
>> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
>> You received this message because you are subscribed to the Google
>> Groups "nodejs" group.
>> To post to this group, send email to [email protected]
>> To unsubscribe from this group, send email to
>> [email protected]
>> For more options, visit this group at
>> http://groups.google.com/group/nodejs?hl=en?hl=en
>>
>  --
> Job Board: http://jobs.nodejs.org/
> Posting guidelines:
> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> You received this message because you are subscribed to the Google
> Groups "nodejs" group.
> To post to this group, send email to [email protected]
> To unsubscribe from this group, send email to
> [email protected]
> For more options, visit this group at
> http://groups.google.com/group/nodejs?hl=en?hl=en
>

-- 
Job Board: http://jobs.nodejs.org/
Posting guidelines: 
https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

Reply via email to