際際滷

際際滷Share a Scribd company logo
continuation-local storage
https://github.com/othiym23/continuationlocal-storage
cls
needed a way to pass around per-request state that wouldnt break (or
change) user code

stashing state on the side of req and res is yucky

thread-local storage is nice but Node is single-threaded

and were thinking about chains of continuations, so each set of values
needs to be tied to a speci鍖c request chain
a dirt-simple example
var	
 cls	
 =	
 require('continuation-足local-足storage');	
 
	
 	
 
function	
 magic()	
 {	
 
	
 	
 console.log("value	
 is	
 %s",	
 cls.getNamespace('test').get('value'));	
 
}	
 
	
 	
 
var	
 test	
 =	
 cls.createNamespace('test');	
 
test.run(function	
 ()	
 {	
 
	
 	
 test.set('value',	
 'hi	
 there!');	
 
	
 	
 setImmediate(magic);	
 
});	
 
test.set('value',	
 'oh	
 no!');
things to note
magic does not have test in scope

inside test.run, values have their own scope

tests values persist across the call to setImmediate
whats going on?
namespace.run clones the current context

the contexts are entered and exited like domains

the state is persisted across process.nextTick, timers, and all other core
async functions
{create,add,remove}AsyncListener
https://github.com/joyent/node/pull/6011
https://github.com/othiym23/async-listener
THERES NO WAY IM LETTING ANOTHER THING AS SLOW AS DOMAINS IN CORE
 TREVNORRIS
srs bzns
very powerful but low-level API

captures every async event in the Node process and makes it observable

makes it simple to pass state to callbacks without changing their code

also makes it easy to write global error handlers that have some state
the API
a listener function that is 鍖red for every async event, returns a value that
will be passed to the decorators on this async events callbacks

a bundle of optional before, after, and error callbacks that will be wrapped
around functions that this async event is responsible for

an optional value that can be passed to before / after / error instead of the
results of the listener
how it go??!
in 0.11.8 and earlier, a JavaScript poly鍖ll that monkeypatches all the things
(so, pretty slow)

in 0.11.9+, a whole bunch of code in C++ and JavaScript (but still, not a
performance king)
how it stable?
poly鍖ll has pretty good coverage, doesnt appear to slow apps down too
much in practice (just recently solidi鍖ed enough)

poly鍖ll is in use in the New Relic transaction tracer

the native version is stable enough that Trevor rewrote domains to use it
(and got a nice performance boost when domains arent in use)
what for?
CLS, obviously

low-level logging modules

pure JS pro鍖lers

long stacktrace modules

making the details of asynchronous execution more observable, basically

More Related Content

CLS & asyncListener: asynchronous observability for Node.js

  • 2. cls needed a way to pass around per-request state that wouldnt break (or change) user code stashing state on the side of req and res is yucky thread-local storage is nice but Node is single-threaded and were thinking about chains of continuations, so each set of values needs to be tied to a speci鍖c request chain
  • 3. a dirt-simple example var cls = require('continuation-足local-足storage'); function magic() { console.log("value is %s", cls.getNamespace('test').get('value')); } var test = cls.createNamespace('test'); test.run(function () { test.set('value', 'hi there!'); setImmediate(magic); }); test.set('value', 'oh no!');
  • 4. things to note magic does not have test in scope inside test.run, values have their own scope tests values persist across the call to setImmediate
  • 5. whats going on? namespace.run clones the current context the contexts are entered and exited like domains the state is persisted across process.nextTick, timers, and all other core async functions
  • 7. THERES NO WAY IM LETTING ANOTHER THING AS SLOW AS DOMAINS IN CORE TREVNORRIS
  • 8. srs bzns very powerful but low-level API captures every async event in the Node process and makes it observable makes it simple to pass state to callbacks without changing their code also makes it easy to write global error handlers that have some state
  • 9. the API a listener function that is 鍖red for every async event, returns a value that will be passed to the decorators on this async events callbacks a bundle of optional before, after, and error callbacks that will be wrapped around functions that this async event is responsible for an optional value that can be passed to before / after / error instead of the results of the listener
  • 10. how it go??! in 0.11.8 and earlier, a JavaScript poly鍖ll that monkeypatches all the things (so, pretty slow) in 0.11.9+, a whole bunch of code in C++ and JavaScript (but still, not a performance king)
  • 11. how it stable? poly鍖ll has pretty good coverage, doesnt appear to slow apps down too much in practice (just recently solidi鍖ed enough) poly鍖ll is in use in the New Relic transaction tracer the native version is stable enough that Trevor rewrote domains to use it (and got a nice performance boost when domains arent in use)
  • 12. what for? CLS, obviously low-level logging modules pure JS pro鍖lers long stacktrace modules making the details of asynchronous execution more observable, basically