Skip to content

Commit

Permalink
feat(zone.js): Update to the simpler Async Stack Tagging v2 API (#46958)
Browse files Browse the repository at this point in the history
Signed-off-by: Victor Porof <victorporof@chromium.org>

PR Close #46958
  • Loading branch information
victorporof authored and dylhunn committed Aug 4, 2022
1 parent 2b4d7f6 commit f23232f
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 54 deletions.
48 changes: 17 additions & 31 deletions packages/zone.js/lib/zone-spec/async-stack-tagging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,58 +7,44 @@
*/

interface Console {
scheduleAsyncTask(name: string, recurring?: boolean): number;
startAsyncTask(task: number): void;
finishAsyncTask(task: number): void;
cancelAsyncTask(task: number): void;
createTask(name: string): ConsoleTask;
}

interface ConsoleTask {
run<T>(f: () => T): void;
}

interface Task {
asyncId?: number;
consoleTask?: ConsoleTask;
}

class AsyncStackTaggingZoneSpec implements ZoneSpec {
scheduleAsyncTask: Console['scheduleAsyncTask'];
startAsyncTask: Console['startAsyncTask'];
finishAsyncTask: Console['finishAsyncTask'];
cancelAsyncTask: Console['finishAsyncTask'];
createTask: Console['createTask'];

constructor(namePrefix: string, consoleAsyncStackTaggingImpl: Console = console) {
this.name = 'asyncStackTagging for ' + namePrefix;
this.scheduleAsyncTask = consoleAsyncStackTaggingImpl?.scheduleAsyncTask ?? (() => {});
this.startAsyncTask = consoleAsyncStackTaggingImpl?.startAsyncTask ?? (() => {});
this.finishAsyncTask = consoleAsyncStackTaggingImpl?.finishAsyncTask ?? (() => {});
this.cancelAsyncTask = consoleAsyncStackTaggingImpl?.cancelAsyncTask ?? (() => {});
this.createTask = consoleAsyncStackTaggingImpl?.createTask ?? (() => {});
}

// ZoneSpec implementation below.

name: string;

onScheduleTask(delegate: ZoneDelegate, current: Zone, target: Zone, task: Task): Task {
task.asyncId = this.scheduleAsyncTask(
task.source || task.type, task.data?.isPeriodic || task.type === 'eventTask');
onScheduleTask(delegate: ZoneDelegate, _current: Zone, target: Zone, task: Task): Task {
task.consoleTask = this.createTask(`Zone - ${task.source || task.type}`);
return delegate.scheduleTask(target, task);
}

onInvokeTask(
delegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task, applyThis: any,
delegate: ZoneDelegate, _currentZone: Zone, targetZone: Zone, task: Task, applyThis: any,
applyArgs?: any[]) {
task.asyncId && this.startAsyncTask(task.asyncId);
try {
return delegate.invokeTask(targetZone, task, applyThis, applyArgs);
} finally {
task.asyncId && this.finishAsyncTask(task.asyncId);
if (task.type !== 'eventTask' && !task.data?.isPeriodic) {
task.asyncId = undefined;
}
let ret;
if (task.consoleTask) {
ret = task.consoleTask.run(() => delegate.invokeTask(targetZone, task, applyThis, applyArgs));
} else {
ret = delegate.invokeTask(targetZone, task, applyThis, applyArgs);
}
}

onCancelTask(delegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task) {
task.asyncId && this.cancelAsyncTask(task.asyncId);
task.asyncId = undefined;
return delegate.cancelTask(targetZone, task);
return ret;
}
}

Expand Down
47 changes: 24 additions & 23 deletions packages/zone.js/test/zone-spec/async-tagging-console.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,51 +12,55 @@ describe('AsyncTaggingConsoleTest', () => {
const AsyncStackTaggingZoneSpec = (Zone as any)['AsyncStackTaggingZoneSpec'];

describe('should call console async stack tagging API', () => {
let idx = 1;
const scheduleAsyncTaskSpy = jasmine.createSpy('scheduleAsyncTask').and.callFake(() => {
return idx++;
});
const startAsyncTaskSpy = jasmine.createSpy('startAsyncTask');
const finishAsyncTaskSpy = jasmine.createSpy('finishAsyncTask');
const cancelAsyncTaskSpy = jasmine.createSpy('cancelAsyncTask');
const scheduleAsyncTaskSpy = jasmine.createSpy('scheduleAsyncTask').and.callFake(() => {
return {
run: (f: () => unknown) => {
startAsyncTaskSpy();
const retval = f();
finishAsyncTaskSpy();
return retval;
},
};
});

let asyncStackTaggingZone: Zone;

beforeEach(() => {
scheduleAsyncTaskSpy.calls.reset();
startAsyncTaskSpy.calls.reset();
finishAsyncTaskSpy.calls.reset();
cancelAsyncTaskSpy.calls.reset();
asyncStackTaggingZone = Zone.current.fork(new AsyncStackTaggingZoneSpec('test', {
scheduleAsyncTask: scheduleAsyncTaskSpy,
startAsyncTask: startAsyncTaskSpy,
finishAsyncTask: finishAsyncTaskSpy,
cancelAsyncTask: cancelAsyncTaskSpy,
createTask: scheduleAsyncTaskSpy,
}));
});

it('setTimeout', (done: DoneFn) => {
asyncStackTaggingZone.run(() => {
setTimeout(() => {});
});
setTimeout(() => {
expect(scheduleAsyncTaskSpy).toHaveBeenCalledWith('setTimeout', false);
expect(scheduleAsyncTaskSpy).toHaveBeenCalledWith('Zone - setTimeout');
expect(startAsyncTaskSpy.calls.count()).toBe(1);
expect(finishAsyncTaskSpy.calls.count()).toBe(1);
done();
});
});

it('clearTimeout', (done: DoneFn) => {
asyncStackTaggingZone.run(() => {
const id = setTimeout(() => {});
clearTimeout(id);
});
setTimeout(() => {
expect(scheduleAsyncTaskSpy).toHaveBeenCalledWith('setTimeout', false);
expect(scheduleAsyncTaskSpy).toHaveBeenCalledWith('Zone - setTimeout');
expect(startAsyncTaskSpy).not.toHaveBeenCalled();
expect(finishAsyncTaskSpy).not.toHaveBeenCalled();
expect(cancelAsyncTaskSpy.calls.count()).toBe(1);
done();
});
});

it('setInterval', (done: DoneFn) => {
asyncStackTaggingZone.run(() => {
let count = 0;
Expand All @@ -68,19 +72,19 @@ describe('AsyncTaggingConsoleTest', () => {
}, 10);
});
setTimeout(() => {
expect(scheduleAsyncTaskSpy).toHaveBeenCalledWith('setInterval', true);
expect(scheduleAsyncTaskSpy).toHaveBeenCalledWith('Zone - setInterval');
expect(startAsyncTaskSpy.calls.count()).toBe(2);
expect(finishAsyncTaskSpy.calls.count()).toBe(1);
expect(cancelAsyncTaskSpy.calls.count()).toBe(1);
expect(finishAsyncTaskSpy.calls.count()).toBe(2);
done();
}, 50);
});

it('Promise', (done: DoneFn) => {
asyncStackTaggingZone.run(() => {
Promise.resolve(1).then(() => {});
});
setTimeout(() => {
expect(scheduleAsyncTaskSpy).toHaveBeenCalledWith('Promise.then', false);
expect(scheduleAsyncTaskSpy).toHaveBeenCalledWith('Zone - Promise.then');
expect(startAsyncTaskSpy.calls.count()).toBe(1);
expect(finishAsyncTaskSpy.calls.count()).toBe(1);
done();
Expand All @@ -94,12 +98,10 @@ describe('AsyncTaggingConsoleTest', () => {
Zone.root.run(() => {
setTimeout(() => {
expect(scheduleAsyncTaskSpy.calls.all()[0].args).toEqual([
'XMLHttpRequest.addEventListener:load',
true,
'Zone - XMLHttpRequest.addEventListener:load',
]);
expect(scheduleAsyncTaskSpy.calls.all()[1].args).toEqual([
'XMLHttpRequest.send',
false,
'Zone - XMLHttpRequest.send',
]);
expect(startAsyncTaskSpy.calls.count()).toBe(2);
expect(finishAsyncTaskSpy.calls.count()).toBe(2);
Expand All @@ -124,10 +126,9 @@ describe('AsyncTaggingConsoleTest', () => {
button.dispatchEvent(clickEvent);
button.removeEventListener('click', handler);
expect(scheduleAsyncTaskSpy)
.toHaveBeenCalledWith('HTMLButtonElement.addEventListener:click', true);
.toHaveBeenCalledWith('Zone - HTMLButtonElement.addEventListener:click');
expect(startAsyncTaskSpy.calls.count()).toBe(2);
expect(finishAsyncTaskSpy.calls.count()).toBe(2);
expect(cancelAsyncTaskSpy.calls.count()).toBe(1);
});
}));
});
Expand Down

0 comments on commit f23232f

Please sign in to comment.