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.

 

-- 
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 nodejs@googlegroups.com
To unsubscribe from this group, send email to
nodejs+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

Reply via email to