On Wednesday, November 14, 2012 at 2:28 PM, pie_lard wrote:
> On Wednesday, 14 November 2012 22:04:15 UTC, Forrest L Norvell wrote:
> > On Wednesday, November 14, 2012 at 1:35 PM, pie_lard wrote:
> > > Suppose node were changed to remove the feature that lets domains track 
> > > EventEmitters.  So domain.add(), .remove() and .members would all be 
> > > removed.  The code that automatically adds new EventEmitters to the 
> > > active domain (if there is one) would also be deleted.  Finally, suppose 
> > > .bind() and .intercept() were also removed.
> > > 
> > 
> > As an aside, you should only have to call domain.{add,remove} on a handle 
> > or an emitter yourself under very specific (and rare) conditions.
> > > That would just leave domain.run() - plus the ability to create new 
> > > domains and possibly nest them.
> > > 
> > > Would that be enough to effectively recreate synchronous stack-based 
> > > exception handling?
> > No, and I'll explain why below. 
> > > My answer would be yes - and in fact it would remove my connection-pool 
> > > problem altogether without any need for the 3rd-party module authors to 
> > > change anything.
> > > 
> > > To put it another way; in what real-world circumstances would you need 
> > > the features I just removed?
> > > 
> > > Please understand I ask this as a bit of a node noob ;)  It's not a 
> > > criticism of domains - I would like someone to explain why I'm wrong 
> > > about this.
> > The problem is it's impossible to know in advance whether a chunk of code 
> > is going to use EventEmitters or not, and without domain code there to wrap 
> > them, you'd lose the necessary state to tie a specific request to a 
> > specific domain. Consider the following (buggy / incomplete) Express 
> > handler:
> > 
> > app.get('/test', function (req, res) {
> >   var d = domain.create();
> >   d.on('error', function (error) { res.send(500, 
> > {"content-type":"text/plain"}, error.stack); });
> >   d.run(function () {
> >     fs.readFile(FILENAME, 'utf-8', function (err, contents) {
> >       // process.domain should be available here
> >       res.send(contents.replace(/:/gm, '/'));
> >     });
> >   });
> > });
> > 
> > 
> > 
> > 
> > 
> > The call to res.send is going to happen several passes through the event 
> > loop after the initial handler is called. It's entirely possible that in 
> > the time the file is read from disk, another several requests to that 
> > handler are going to have come in to the server. Without dealing with the 
> > EventEmitters, how will any errors emitted inside the fs.readFile callback 
> > be connected back to the enclosing domain?
> > 
> Maybe this is what I'm misunderstanding!  I was under the impression that 
> your example would in fact work (ie. that your domain handler would catch an 
> error thrown by the res.send() call).
> 
> The docs say:
> 
> Additionally, callbacks passed to lowlevel event loop requests (such as to 
> fs.open, or other callback-taking methods) will automatically be bound to the 
> active domain. If they throw, then the domain will catch the error.
> 
> Doesn't that imply that you've done all you need to do in the above code?  
> That just by starting the chain of callbacks inside run() that the active 
> domain will persist through them?  And that as you're creating a new domain 
> per request the domains won't get confused - the correct res object will be 
> available when an error is thrown?
> 
> BTW: I didn't mean to imply that the domain code inside node could do this 
> without wrapping EventEmitters or something similar.  Just that (a) it should 
> do so behind-the-scenes and (b) the wrapping shouldn't take the form of 
> binding the EventEmitter to whatever domain happens to be active when the 
> emitter was created.
I think we're very close to getting in sync here. Yes, with the domains code 
internally wrapping EventEmitters, the above is totally enough to trap errors 
on the correct domain. I was asking how that would work *without* EventEmitters 
being wrapped. 

You shouldn't have to deal with any of the EventEmitter stuff. It should all be 
handled for you as an app developer behind the scenes. domain.add / domain.bind 
/ domain.intercept are mostly for the use of a small subset of Node developers 
who maintain modules that use long-lived EventEmitters shared among a number of 
clients. If / when those modules are patched to work with domains, your need as 
an end user to deal with any of this stuff should vanish. At that point, yes, 
you should just be able to call domain.run() within your handlers and 
everything should Just Work. Sorry if I haven't made that clearer!

F

-- 
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