Skip to content

Commit 848a009

Browse files
JiaLiPassionthePunderWoman
authored andcommitted
feat(zone.js): add AsyncStackTaggingZoneSpec implementation (#46693)
Chrome has an experimental API to improve the debug experience of the async tasks. The details can be found here https://bugs.chromium.org/p/chromium/issues/detail?id=332624#c29 This commit add the `async stack tagging` support in the `zone.js`. User can `import 'zone.js/plugins/async-stack-tagging';` to enable this feature. PR Close #46693
1 parent b6a950c commit 848a009

File tree

13 files changed

+237
-5
lines changed

13 files changed

+237
-5
lines changed

packages/zone.js/bundles.bzl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ BUNDLES_ENTRY_POINTS = {
1919
"async-test": {
2020
"entrypoint": _DIR + "testing/async-testing",
2121
},
22+
"async-stack-tagging": {
23+
"entrypoint": _DIR + "zone-spec/async-stack-tagging",
24+
},
2225
"fake-async-test": {
2326
"entrypoint": _DIR + "testing/fake-async",
2427
},

packages/zone.js/dist/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ js_library(
4545
filegroup(
4646
name = "dist_bundle_group",
4747
srcs = [
48+
":async-stack-tagging.js",
49+
":async-stack-tagging.min.js",
4850
":async-test.js",
4951
":async-test.min.js",
5052
":fake-async-test.js",

packages/zone.js/dist/tools.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ ES5_BUNDLES = [
44
"zone-node",
55
"zone-testing-node-bundle",
66
"async-test",
7+
"async-stack-tagging",
78
"fake-async-test",
89
"long-stack-trace-zone",
910
"proxy",
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
interface Console {
10+
scheduleAsyncTask(name: string, recurring?: boolean): number;
11+
startAsyncTask(task: number): void;
12+
finishAsyncTask(task: number): void;
13+
cancelAsyncTask(task: number): void;
14+
}
15+
16+
interface Task {
17+
asyncId?: number;
18+
}
19+
20+
class AsyncStackTaggingZoneSpec implements ZoneSpec {
21+
scheduleAsyncTask: Console['scheduleAsyncTask'];
22+
startAsyncTask: Console['startAsyncTask'];
23+
finishAsyncTask: Console['finishAsyncTask'];
24+
cancelAsyncTask: Console['finishAsyncTask'];
25+
26+
constructor(namePrefix: string, consoleAsyncStackTaggingImpl: Console = console) {
27+
this.name = 'asyncStackTagging for ' + namePrefix;
28+
this.scheduleAsyncTask = consoleAsyncStackTaggingImpl?.scheduleAsyncTask ?? (() => {});
29+
this.startAsyncTask = consoleAsyncStackTaggingImpl?.startAsyncTask ?? (() => {});
30+
this.finishAsyncTask = consoleAsyncStackTaggingImpl?.finishAsyncTask ?? (() => {});
31+
this.cancelAsyncTask = consoleAsyncStackTaggingImpl?.cancelAsyncTask ?? (() => {});
32+
}
33+
34+
// ZoneSpec implementation below.
35+
36+
name: string;
37+
38+
onScheduleTask(delegate: ZoneDelegate, current: Zone, target: Zone, task: Task): Task {
39+
task.asyncId = this.scheduleAsyncTask(
40+
task.source || task.type, task.data?.isPeriodic || task.type === 'eventTask');
41+
return delegate.scheduleTask(target, task);
42+
}
43+
44+
onInvokeTask(
45+
delegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task, applyThis: any,
46+
applyArgs?: any[]) {
47+
task.asyncId && this.startAsyncTask(task.asyncId);
48+
try {
49+
return delegate.invokeTask(targetZone, task, applyThis, applyArgs);
50+
} finally {
51+
task.asyncId && this.finishAsyncTask(task.asyncId);
52+
if (task.type !== 'eventTask' && !task.data?.isPeriodic) {
53+
task.asyncId = undefined;
54+
}
55+
}
56+
}
57+
58+
onCancelTask(delegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task) {
59+
task.asyncId && this.cancelAsyncTask(task.asyncId);
60+
task.asyncId = undefined;
61+
return delegate.cancelTask(targetZone, task);
62+
}
63+
}
64+
65+
// Export the class so that new instances can be created with proper
66+
// constructor params.
67+
(Zone as any)['AsyncStackTaggingZoneSpec'] = AsyncStackTaggingZoneSpec;

packages/zone.js/plugins/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package(default_visibility = ["//visibility:public"])
33
filegroup(
44
name = "plugin_bundle_group",
55
srcs = [
6+
"//packages/zone.js/plugins:async-stack-tagging.min/package.json",
7+
"//packages/zone.js/plugins:async-stack-tagging/package.json",
68
"//packages/zone.js/plugins:async-test.min/package.json",
79
"//packages/zone.js/plugins:async-test/package.json",
810
"//packages/zone.js/plugins:fake-async-test.min/package.json",
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "zone.js/async-stack-tagging.min",
3+
"main": "../../bundles/async-stack-tagging.umd.min.js",
4+
"fesm2015": "../../fesm2015/async-stack-tagging.min.js",
5+
"es2015": "../../fesm2015/async-stack-tagging.min.js",
6+
"module": "../../fesm2015/async-stack-tagging.min.js"
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "zone.js/async-stack-tagging",
3+
"main": "../../bundles/async-stack-tagging.umd.js",
4+
"fesm2015": "../../fesm2015/async-stack-tagging.js",
5+
"es2015": "../../fesm2015/async-stack-tagging.js",
6+
"module": "../../fesm2015/async-stack-tagging.js"
7+
}

packages/zone.js/test/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ ts_library(
3434
exclude = [
3535
"common/Error.spec.ts",
3636
"common/promise-disable-wrap-uncaught-promise-rejection.spec.ts",
37+
"zone-spec/async-tagging-console.spec.ts",
3738
],
3839
),
3940
deps = [
@@ -264,6 +265,7 @@ test_srcs = glob(
264265
"jasmine-patch.spec.ts",
265266
"common_tests.ts",
266267
"browser_entry_point.ts",
268+
"zone-spec/async-tagging-console.spec.ts",
267269
]
268270

269271
test_deps = [

packages/zone.js/test/browser-zone-setup.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import '../lib/browser/webapis-media-query';
2121
import '../lib/testing/zone-testing';
2222
import '../lib/zone-spec/task-tracking';
2323
import '../lib/zone-spec/wtf';
24+
import '../lib/zone-spec/async-stack-tagging';
2425
import '../lib/extra/cordova';
2526
import '../lib/testing/promise-testing';
2627
import '../lib/testing/async-testing';

packages/zone.js/test/browser_entry_point.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88
import '../lib/common/error-rewrite';
9-
109
// import 'core-js/features/set';
1110
// import 'core-js/features/map';
1211
// List all tests here:
@@ -30,3 +29,4 @@ import './jasmine-patch.spec';
3029
import './browser/messageport.spec';
3130
import './extra/cordova.spec';
3231
import './browser/queue-microtask.spec';
32+
import './zone-spec/async-tagging-console.spec';

0 commit comments

Comments
 (0)