Node.jsでThreadLocal変数的なやつ
TL;DR
Node.jsでスレッドローカル変数を使うような処理を実現したい場合
が使えるかもという話です。
きっかけ
に書いているようなユースケースです。
モデル層とかサービス層(とにかく、コントローラ層より深いところ)でHTTP Requestでやって来た情報(APIバージョンだとか、ユーザエージェントだとか)
を使いたい場合、Node.jsだとスレッドローカル変数みたいなのは使えません。
代替案として、パッと思い浮かぶのは第1引数に必要な情報の詰まったオブジェクトをひたすら引き渡し続けるように規約で縛るくらいだけど
それもイケてないなぁと。
JavaだとThreadLocal
とかで一発なんだけど、なんかないだろうか?
一応あった
ググって見た感じ、othiym23という有名な方が
なissueを上げており、
なものを作ったみたいでした。
使い方
ソース
a.js
'use strict'; var createNamespace = require('continuation-local-storage').createNamespace; var session = createNamespace('my session'); var finish = require('./b'); module.exports = 1; function handle(obj) { session.set('obj', obj); } session.run(function() { var obj = { count: 1, }; handle(obj); setTimeout(function() { finish(); }, 2000); }); session.run(function() { var obj = { count: 2, }; handle(obj); setTimeout(function() { finish(); }, 1000); });
b.js
'use strict'; var getNamespace = require('continuation-local-storage').getNamespace; var session = getNamespace('my session'); module.exports = function() { var obj = session.get('obj'); console.log(obj); }
実行
node a.js // { count: 2 } // { count: 1 }
何が実現できた?
タイミングによらずsession.run(function() {})
のスコープで設定したオブジェクトを
session.get('obj');
で取得できているようです。
あんま使ったことないですが、Node.jsのdomainっぽいですね。 https://nodejs.org/api/domain.html
まとめ
パフォーマンス的な部分は検証してないので、何ともですが、なんとなく使えそうな気はしています。
この記事を見た人で、実際使っているとか、もっといい方法があるとかあれば、教えていただければ幸いです。
補足
も
This is similar to the concept of thread-local data in Java.
とあり、求めていたものズバリでした。
が、まだまだ開発中とのことで、本番導入は無理かなぁというところです。