1 | const fs = require('fs')
|
2 | const async_hooks = require('async_hooks')
|
3 |
|
4 | function log (...args) {
|
5 | process.env.DEBUG_CLS && fs.writeSync(1, args.join(' ') + '\n')
|
6 | }
|
7 |
|
8 | const context = new Map()
|
9 |
|
10 | async_hooks.createHook({
|
11 | init (asyncId, type, triggerAsyncId, resource) {
|
12 | log('Init: ', `${type}(asyncId=${asyncId}, parentAsyncId: ${triggerAsyncId})`)
|
13 | if (context.has(triggerAsyncId)) {
|
14 | context.set(asyncId, context.get(triggerAsyncId))
|
15 | }
|
16 | },
|
17 | before (asyncId) {
|
18 | log('Before: ', asyncId)
|
19 | },
|
20 | after (asyncId) {
|
21 | log('After: ', asyncId)
|
22 | context.delete(asyncId)
|
23 | },
|
24 | destroy (asyncId) {
|
25 | log('Destory: ', asyncId);
|
26 | context.delete(asyncId)
|
27 | }
|
28 | }).enable()
|
29 |
|
30 |
|
31 | class Session {
|
32 | constructor () {
|
33 |
|
34 | this.context = context
|
35 | }
|
36 |
|
37 | get (key) {
|
38 | const asyncId = async_hooks.executionAsyncId()
|
39 | const store = this.context.get(asyncId)
|
40 | if (store) {
|
41 | return store.get(key)
|
42 | }
|
43 | }
|
44 |
|
45 | set (key, value) {
|
46 | const asyncId = async_hooks.executionAsyncId()
|
47 | const store = this.context.get(asyncId)
|
48 | if (store) {
|
49 | store.set(key, value)
|
50 | }
|
51 | }
|
52 |
|
53 | async scope (fn) {
|
54 | await Promise.resolve()
|
55 | const asyncId = async_hooks.executionAsyncId()
|
56 | log('\nScope:', asyncId)
|
57 | this.context.set(asyncId, new Map())
|
58 | const value = await fn()
|
59 | log('\nFinish: ', asyncId)
|
60 | return value
|
61 | }
|
62 | }
|
63 |
|
64 | module.exports = Session
|
65 |
|