Hacker News new | comments | show | ask | jobs | submit login
Show HN: Zones for Node.js using async_hooks (github.com)
25 points by cztomsik 7 months ago | hide | past | web | favorite | 19 comments

"A Zone is an execution context that persists across async tasks. You can think of it as thread-local storage for JavaScript VMs."

In case anyone else was wondering.

Like a closure !?

More like a context, any function can then access data relative to current request, transaction, and similar "async" flows. This is otherwise impossible with async/await.

The reason we don't have zones in Node is because they mess up with error handling. I recommend anyone considering Zones to read trevnorris's domain postmortem https://gist.github.com/trevnorris/d19addf4aa09a0a31a4a14e90...

This sounds like zones are bad idea but those problems are related only to process.nextTick and setTimeout, if you're using promises (which I do for 99.9% things) you're fine.

If you're using promises and async/await then you don't have any of those problems anyway :)

Pure async/await does not allow to track any contextual state - like current transaction/request.

Note that this is based on experimental functionality in NodeJS. Similar functionality had been inside NodeJS before and was removed. This is mostly used internally for other stuff.

This is similar to dynamic scoping.

The Async Hooks API is still experimental but should be stabilized by Node.js 10.

By "similar functionality" are you talking about domains? If so, it's been deprecated for quite a while, but has never been removed.

Good point.

Can someone please compare both?

Does the fact that Minizone is based on "async_hooks" make it more future proof? Less hacky?

Zone.js is an existing library to try and provide CLS in javascript. async_hooks is an experimental API being built in to node to allow this.

The OP is a project implementing a zone.js-style API using async_hooks. Also see this PR on the original zone.js project where they are working to use this in the original library, but have hit many edge cases/issues: https://github.com/angular/zone.js/pull/795

A few years back I wrote something similar for ClojureScript: https://github.com/binaryage/cljs-zones

The drawback was the need to manually wrap all participating async functions into a special macro (zones/bound-fn). With async_hooks this could be automated I believe.

I've always been under the impression that concepts like thread/continuation-local storage were generally discouraged, but I never fully understood the reason.

Obviously, you'd want to avoid coupling your code to an HTTP-specific context if you want to expose a gRPC endpoint in the future.

Are there any other downsides to this approach?

The problem is that all CLS systems in JS are inherently leaky, due to the many games JS libraries/apps can (and do) play with resource pooling. Implementors basically have to play a plug-the-holes game getting all the popular libraries to properly "play along" with the CLS system. For example, domains needed tons of PRs very similar in nature to this: https://github.com/sequelize/sequelize/pull/589/files#diff-1...

Also, they typically come with a sizable perf hit: https://github.com/bmeurer/async-hooks-performance-impact

Useful if you need "contextual" async/await (access current transaction, request, ...)

Perfect! We used domains for this but the module was marked as deprecated and it stressed me out, knowing that we depend on a deprecated concept that will be removed soon.

Now all I need to do is to abstract domain usage so when the time cones I can switch to Zones.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact