Repository navigation
async_hooks: AsyncLocalStorage to diagnostics_channel integration #45277
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
0438150
f8605a6
789d1e0
e72265b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
…ames
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -30,13 +30,15 @@ class ActiveChannel { | |||||
| subscribe(subscription) { | ||||||
| validateFunction(subscription, 'subscription'); | ||||||
| ArrayPrototypePush(this._subscribers, subscription); | ||||||
| this._weak.incRef(); | ||||||
| } | ||||||
|
|
||||||
| unsubscribe(subscription) { | ||||||
| const index = ArrayPrototypeIndexOf(this._subscribers, subscription); | ||||||
| if (index === -1) return false; | ||||||
|
|
||||||
| ArrayPrototypeSplice(this._subscribers, index, 1); | ||||||
| this._weak.decRef(); | ||||||
|
|
||||||
| // When there are no more active subscribers, restore to fast prototype. | ||||||
| if (!this._subscribers.length) { | ||||||
|
|
@@ -68,6 +70,7 @@ class ActiveChannel { | |||||
| class Channel { | ||||||
| constructor(name) { | ||||||
| this._subscribers = undefined; | ||||||
| this._weak = undefined; | ||||||
| this.name = name; | ||||||
| } | ||||||
|
|
||||||
|
|
@@ -107,24 +110,17 @@ function channel(name) { | |||||
| } | ||||||
|
|
||||||
| channel = new Channel(name); | ||||||
| channels[name] = new WeakReference(channel); | ||||||
| channel._weak = new WeakReference(channel); | ||||||
| channels[name] = channel._weak; | ||||||
| return channel; | ||||||
| } | ||||||
|
|
||||||
| function subscribe(name, subscription) { | ||||||
| const chan = channel(name); | ||||||
| channels[name].incRef(); | ||||||
| chan.subscribe(subscription); | ||||||
| return channel(name).subscribe(subscription); | ||||||
| } | ||||||
|
|
||||||
| function unsubscribe(name, subscription) { | ||||||
| const chan = channel(name); | ||||||
| if (!chan.unsubscribe(subscription)) { | ||||||
| return false; | ||||||
| } | ||||||
|
|
||||||
| channels[name].decRef(); | ||||||
| return true; | ||||||
| return channel(name).unsubscribe(subscription); | ||||||
| } | ||||||
|
|
||||||
| function hasSubscribers(name) { | ||||||
|
|
@@ -139,46 +135,54 @@ function hasSubscribers(name) { | |||||
| } | ||||||
|
|
||||||
| class TracingChannel { | ||||||
| #channels; | ||||||
|
|
||||||
| constructor(name) { | ||||||
| this.name = name; | ||||||
| this.channels = { | ||||||
| start: channel(`${name}.start`), | ||||||
| end: channel(`${name}.end`), | ||||||
| asyncEnd: channel(`${name}.asyncEnd`), | ||||||
| error: channel(`${name}.error`) | ||||||
| this.#channels = { | ||||||
| start: new Channel(Symbol(`tracing.start`)), | ||||||
| end: new Channel(Symbol(`tracing.end`)), | ||||||
| asyncEnd: new Channel(Symbol(`tracing.asyncEnd`)), | ||||||
| error: new Channel(Symbol(`tracing.error`)) | ||||||
| }; | ||||||
| } | ||||||
|
|
||||||
| // Attach WeakReference to all the sub-channels so the liveness management | ||||||
| // in subscribe/unsubscribe keeps the TracingChannel the sub-channels are | ||||||
| // attached to alive. | ||||||
| set _weak(weak) { | ||||||
| for (const key in this.#channels) { | ||||||
| this.#channels[key]._weak = weak; | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| get hasSubscribers() { | ||||||
| const { channels } = this; | ||||||
| for (const key in channels) { | ||||||
| if (channels[key].hasSubscribers) return true; | ||||||
| for (const key in this.#channels) { | ||||||
| if (this.#channels[key].hasSubscribers) { | ||||||
| return true; | ||||||
| } | ||||||
| } | ||||||
| return false; | ||||||
| } | ||||||
|
|
||||||
| subscribe(handlers) { | ||||||
| let subscribed = true; | ||||||
| for (const key in handlers) { | ||||||
| if (!subscribe(`${this.name}.${key}`, handlers[key])) { | ||||||
| subscribed = false; | ||||||
| } | ||||||
| this.#channels[key]?.subscribe(handlers[key]); | ||||||
| } | ||||||
| return subscribed; | ||||||
| } | ||||||
|
|
||||||
| unsubscribe(handlers) { | ||||||
| let unsubscribed = true; | ||||||
| for (const key in handlers) { | ||||||
| if (!unsubscribe(`${this.name}.${key}`, handlers[key])) { | ||||||
| unsubscribed = false; | ||||||
| const channel = this.#channels[key]; | ||||||
| if (!channel || !channel.unsubscribe(handlers[key])) { | ||||||
| return false; | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why end the loop just because there is maybe an extra key in the object? |
||||||
| } | ||||||
| } | ||||||
| return unsubscribed; | ||||||
| return true; | ||||||
| } | ||||||
|
|
||||||
| traceSync(fn, ctx = {}, thisArg, ...args) { | ||||||
| const { start, end, error } = this.channels; | ||||||
| const { start, end, error } = this.#channels; | ||||||
| start.publish(ctx); | ||||||
| try { | ||||||
| const result = ReflectApply(fn, thisArg, args); | ||||||
|
|
@@ -194,7 +198,7 @@ class TracingChannel { | |||||
| } | ||||||
|
|
||||||
| tracePromise(fn, ctx = {}, thisArg, ...args) { | ||||||
|
mcollina marked this conversation as resolved.
Outdated
|
||||||
| const { asyncEnd, start, end, error } = this.channels; | ||||||
| const { asyncEnd, start, end, error } = this.#channels; | ||||||
| start.publish(ctx); | ||||||
|
|
||||||
| const reject = (err) => { | ||||||
|
|
@@ -223,7 +227,7 @@ class TracingChannel { | |||||
| } | ||||||
|
|
||||||
| traceCallback(fn, position = 0, ctx = {}, thisArg, ...args) { | ||||||
| const { start, end, asyncEnd, error } = this.channels; | ||||||
| const { start, end, asyncEnd, error } = this.#channels; | ||||||
| start.publish(ctx); | ||||||
|
|
||||||
| function wrap(fn) { | ||||||
|
|
@@ -258,8 +262,22 @@ class TracingChannel { | |||||
| } | ||||||
| } | ||||||
|
|
||||||
| const tracingChannels = ObjectCreate(null); | ||||||
|
|
||||||
| function tracingChannel(name) { | ||||||
| return new TracingChannel(name); | ||||||
| let channel; | ||||||
| const ref = tracingChannels[name]; | ||||||
| if (ref) channel = ref.get(); | ||||||
| if (channel) return channel; | ||||||
|
|
||||||
| if (typeof name !== 'string' && typeof name !== 'symbol') { | ||||||
| throw new ERR_INVALID_ARG_TYPE('tracingChannel', ['string', 'symbol'], name); | ||||||
| } | ||||||
|
|
||||||
| channel = new TracingChannel(name); | ||||||
| channel._weak = new WeakReference(channel); | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| tracingChannels[name] = channel._weak; | ||||||
| return channel; | ||||||
| } | ||||||
|
|
||||||
| module.exports = { | ||||||
|
|
||||||
Uh oh!
There was an error while loading. Please reload this page.