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