Skip to content

Commit 776c042

Browse files
committed
expand support to any iterator
1 parent 50748c5 commit 776c042

File tree

1 file changed

+55
-29
lines changed

1 file changed

+55
-29
lines changed

lib/diagnostics_channel.js

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -431,56 +431,82 @@ class TracingChannel {
431431
});
432432
}
433433

434-
*traceGenerator(fn, context = {}, thisArg, ...args) {
434+
traceIterator(fn, context = {}, thisArg, ...args) {
435435
if (!this.hasSubscribers) {
436436
return ReflectApply(fn, thisArg, args);
437437
}
438438

439-
const { start, end, asyncStart, asyncEnd, error } = this;
439+
const { channel, start, end, asyncStart, asyncEnd, error } = this;
440440

441-
if (!this.#generatorChannel) {
442-
this.#generatorChannel = this.tracingChannel({
443-
start: this.channel(start.name.slice(0, -6) + ':next:start'),
444-
end: this.channel(end.name.slice(0, -4) + ':next:end'),
445-
asyncStart: this.channel(asyncStart.name.slice(0, -11) + ':next:asyncStart'),
446-
asyncEnd: this.channel(asyncEnd.name.slice(0, -9) + ':next:asyncEnd'),
447-
error: this.channel(error.name.slice(0, -6) + ':next:error'),
441+
if (!this.#nextChannel) {
442+
this.#nextChannel = this.tracingChannel({
443+
start: channel(start.name.slice(0, -6) + ':next:start'),
444+
end: channel(end.name.slice(0, -4) + ':next:end'),
445+
asyncStart: channel(asyncStart.name.slice(0, -11) + ':next:asyncStart'),
446+
asyncEnd: channel(asyncEnd.name.slice(0, -9) + ':next:asyncEnd'),
447+
error: channel(error.name.slice(0, -6) + ':next:error'),
448448
});
449449
}
450450

451-
const gen = this.traceSync(fn, context, thisArg, ...args);
451+
const iter = this.#traceMaybePromise(fn, context, thisArg, ...args);
452+
453+
return iter instanceof Promise
454+
? iter.then((iter, method) => {
455+
const { next: iterNext, return: iterReturn, throw: iterThrow } = iter;
452456

453-
gen.next = (...args) => this.traceSync(gen.next, context, gen, ...args);
454-
gen.return = (...args) => this.traceSync(gen.return, context, gen, ...args);
455-
gen.throw = (...args) => this.traceSync(gen.throw, context, gen, ...args);
457+
iter.next = (...args) =>
458+
this.#nextChannel.#traceMaybePromise(iterNext, ctx, iter, ...args);
459+
iter.return = (...args) =>
460+
this.#nextChannel.#traceMaybePromise(iterReturn, ctx, iter, ...args);
461+
iter.throw = (...args) =>
462+
this.#nextChannel.#traceMaybePromise(iterThrow, ctx, iter, ...args);
456463

457-
yield* gen;
464+
return iter;
465+
})
466+
: iter;
458467
}
459468

460-
async *traceAsyncGenerator(fn, context = {}, thisArg, ...args) {
469+
#traceMaybePromise(fn, context = {}, thisArg, ...args) {
461470
if (!this.hasSubscribers) {
462471
return ReflectApply(fn, thisArg, args);
463472
}
464473

465474
const { start, end, asyncStart, asyncEnd, error } = this;
466475

467-
if (!this.#generatorChannel) {
468-
this.#generatorChannel = this.tracingChannel({
469-
start: this.channel(start.name.slice(0, -6) + ':next:start'),
470-
end: this.channel(end.name.slice(0, -4) + ':next:end'),
471-
asyncStart: this.channel(asyncStart.name.slice(0, -11) + ':next:asyncStart'),
472-
asyncEnd: this.channel(asyncEnd.name.slice(0, -9) + ':next:asyncEnd'),
473-
error: this.channel(error.name.slice(0, -6) + ':next:error'),
474-
});
476+
function reject(err) {
477+
context.error = err;
478+
error.publish(context);
479+
asyncStart.publish(context);
480+
// TODO: Is there a way to have asyncEnd _after_ the continuation?
481+
asyncEnd.publish(context);
482+
return PromiseReject(err);
475483
}
476484

477-
const gen = this.traceSync(fn, context, thisArg, ...args);
478-
479-
gen.next = (...args) => this.tracePromise(gen.next, context, gen, ...args);
480-
gen.return = (...args) => this.tracePromise(gen.return, context, gen, ...args);
481-
gen.throw = (...args) => this.tracePromise(gen.throw, context, gen, ...args);
485+
function resolve(result) {
486+
context.result = result;
487+
asyncStart.publish(context);
488+
// TODO: Is there a way to have asyncEnd _after_ the continuation?
489+
asyncEnd.publish(context);
490+
return result;
491+
}
482492

483-
yield* gen;
493+
return start.runStores(context, () => {
494+
try {
495+
const result = ReflectApply(fn, thisArg, args);
496+
// TODO: Should tracePromise just always do this?
497+
if (!(result instanceof Promise)) {
498+
context.result = result
499+
return result
500+
}
501+
return PromisePrototypeThen(result, resolve, reject);
502+
} catch (err) {
503+
context.error = err;
504+
error.publish(context);
505+
throw err;
506+
} finally {
507+
end.publish(context);
508+
}
509+
});
484510
}
485511
}
486512

0 commit comments

Comments
 (0)