On Oct 14, 3:04 am, JeanHuguesRobert <
jeanhuguesrob...@gmail.com>
wrote:
> On Oct 13, 5:42 pm, Bradley Meck <
bradley.m...@gmail.com> wrote:
>
> > I would argue against a global event/emitter as sometimes emitters do
> > not want to be visible to exterior code. As well as that is a slow
> > down for the event loop which is extremely hot code.On Oct 13, 5:42 pm, Bradley Meck <
bradley.m...@gmail.com> wrote:
> > I would argue against a global event/emitter as sometimes emitters do
> > not want to be visible to exterior code. As well as that is a slow
> > down for the event loop which is extremely hot code.
>
> I certainly agree, performance matters. I was not thinking about an
> event "emitter" actually, just about some global "Event.source"
> holding the "this" that callbacks receive.
>
> Using this "Event.source" Bruno could find the locale using
> Event.source.brunoLocale (assuming source is an HttpRequest that was
> previously assigned a brunoLocale attribute).
>
> ... or actually using some (better) Event.context.brunoLocale, because
> the idea of something equivalent to Thread Local Variables in an
> evented environment is nice I think
I think that this would solve my problem. Here is how I understand a
possible implementation:
* We introduce a global Event.context variable that holds the context.
The context is an object that holds all the TLS data.
* We introduce an eventContext property in the EventEmitter class.
* In the constructor of EventEmitter, we assign the global
Event.context to this.eventContext
* In EventEmitter.prototype.emit, we assign this.eventContext to the
global Event.context before invoking the callbacks.
Given this, I should be able to allocate a context in my node
dispatcher and assign it to both Event.context and
request.eventContext. And I should be able to access this context from
any of my callbacks through the global Event.context variable.
This should work for all the event emitters that my code will create
as they will hold the correct event source and will set the global
before invoking callbacks.
But this won't work "as is" for global event emitters. So, it won't
solve my "uncaughtExeption" issue. But what if we use
process.eventContext as global, instead of a separate Event.context
variable? Then, uncaughtException would also be dispatched with the
right context.
But will this really work? Here, I am assuming that all async
callbacks go through an event emitter and an emit call. Is this really
the case ? (I'm only starting to investigate node's internals and I
have the impression that callbacks don't necessarily go through an
emitter). If this is not the case, then this logic would probably need
to be handled at a lower level inside node. Trickier but I don't see
why this could not be done.
> (for as much as anything even
> slightly "global" can be considered "nice" that is).
Global variables have obviously a bad reputation (and they deserve it
unless immutable). But thread local variables are a different story.
Their main use is to hold information about the agent who is
performing the operation: his identity, his locale, his timezone
(although most frameworks don't seem to care much about handling
agents in different timezones), etc. This is information that we
sometimes need in low level modules (date and time formatting for
example) but that we don't want to pass explicity. So, there is a real
use case here.
>
> For example when a FS.readFile()'s callback is called, one would
> usually like to restore the context captured when FS.readFile() was
> called.
>
> Elaborating on my previous "contexted" proposal:
> FS.readFile( xxx, this.contexted( function( err, data ){
> xxxxx using global contexted.scope (& a proper "this")
> }))
> Where
> var contexted = Object.prototype.contexted = function( f ){
> var ctx = contexted.scope
> var that = this
> return function(){
> contexted.scope = ctx
> return f.apply( that, arguments)
> }
>
> }
>
> But 1/tedious 2/slow
>
I agree. This should work but it means a lot of extra code to write,
potential bugs, slower code, etc.
> A solution where both a global Event.source and a global Event.context
> is managed by NodeJS seems much more efficient to me. About 3 or 4
> assignments per event. So the impact on performance should be close to
> zero.
>
> Please note that this also solve the issue with bombing third party
> code, assuming the uncaughtExceptionHandler exceptionally gets the
> Event.context that was active when the exception occurred, instead of
> the context as it was when the handler was registered, as would
> normally happen.
>
> In the debate events vs threads, Event.source might be equivalent to
> the Thread.current that most (all?) thread libraries provide,
> Event.context being similar to Thread Local Variables.
Do we really need two variables? Event.context is probably sufficient,
and I have the impression that we could attach it to the "process"
event emitter, as process.eventContext (but I may be a bit naive about
node here).
Thanks a lot for the response. This is very helpful. Bruno.