cls & asynclistener: asynchronous observability for node.js

12
continuation-local storage https://github.com/othiym23/continuation- local-storage

Upload: forrest-norvell

Post on 24-Jun-2015

2.064 views

Category:

Technology


6 download

DESCRIPTION

Slides from my presentation at PDXNode in October 2013 before RealtimeConf. Thanks to Tracy Abrahms, Ben Acker, and the rest of the PDXNode community for accommodating and hosting me at the last minute!

TRANSCRIPT

Page 1: CLS & asyncListener: asynchronous observability for Node.js

continuation-local storagehttps://github.com/othiym23/continuation-local-storage

Page 2: CLS & asyncListener: asynchronous observability for Node.js

clsneeded a way to pass around per-request state that wouldn’t 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 we’re thinking about chains of continuations, so each set of values needs to be tied to a specific request chain

Page 3: CLS & asyncListener: asynchronous observability for Node.js

a dirt-simple examplevar  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!');  

Page 4: CLS & asyncListener: asynchronous observability for Node.js

things to note

magic does not have test in scope

inside test.run, values have their own scope

test’s values persist across the call to setImmediate

Page 5: CLS & asyncListener: asynchronous observability for Node.js

what’s 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

Page 6: CLS & asyncListener: asynchronous observability for Node.js

{create,add,remove}AsyncListenerhttps://github.com/joyent/node/pull/6011 https://github.com/othiym23/async-listener

Page 7: CLS & asyncListener: asynchronous observability for Node.js

THERE’S NO WAY I’M LETTING ANOTHER THING AS SLOW AS DOMAINS IN CORE – TREVNORRIS

Page 8: CLS & asyncListener: asynchronous observability for Node.js

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

Page 9: CLS & asyncListener: asynchronous observability for Node.js

the APIa listener function that is fired for every async event, returns a value that will be passed to the decorators on this async event’s 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

Page 10: CLS & asyncListener: asynchronous observability for Node.js

how it go??!

in 0.11.8 and earlier, a JavaScript polyfill 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)

Page 11: CLS & asyncListener: asynchronous observability for Node.js

how it stable?polyfill has pretty good coverage, doesn’t appear to slow apps down too much in practice (just recently solidified enough)

polyfill 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 aren’t in use)

Page 12: CLS & asyncListener: asynchronous observability for Node.js

what for?CLS, obviously

low-level logging modules

pure JS profilers

long stacktrace modules

making the details of asynchronous execution more observable, basically