On Wednesday, November 14, 2012 at 3:24 PM, pie_lard wrote:
> On Wednesday, 14 November 2012 22:59:09 UTC, Forrest L Norvell wrote:
> > 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
>
> Yes, we do agree - as an end user I should just have to use run(). However,
> with my suggested approach the authors of the 3rd-party connection pools and
> the like wouldn't have to change anything either. As it is it seems to me
> that they must go and add some code that simply checks whether they are
> running under a domain and if so check they run any callbacks under it. In
> other words they must explicitly write behaviour that could be implemented by
> default inside node.
If the modules aren't patched to be domain-aware, then there's no way to ensure
that the callback is evaluated in the correct domain. How do you think that
would work?
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