Skip to content

Commit

Permalink
fix(core): Explicitly manage TracingSnapshot lifecycle and dispose of…
Browse files Browse the repository at this point in the history
… it once it's been used. (#58929)

Provide a callback to the TracingService implementation when a Snapshot can be disposed.
The underlying tracing implementation may use refcounting and needs to release resources
to enable the trace to complete.

While change detection uses the snapshot for exactly one callback, after render runs
multiple hooks in the sequence so we need a more predictable way to indicate that the snapshot
can be finalized.s

PR Close #58929
  • Loading branch information
arielbackenroth authored and pkozlowski-opensource committed Nov 27, 2024
1 parent 31f73cd commit 4792db9
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/core/src/application/application_ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,7 @@ export class ApplicationRef {
// if one exists. Snapshots may be reference counted by the implementation so
// we want to ensure that if we request a snapshot that we use it.
snapshot.run(TracingAction.CHANGE_DETECTION, this._tick);
snapshot.dispose();
return;
}

Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/application/tracing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ export enum TracingAction {
/** A single tracing snapshot. */
export interface TracingSnapshot {
run<T>(action: TracingAction, fn: () => T): T;

/** Disposes of the tracing snapshot. Must be run exactly once per TracingSnapshot. */
dispose(): void;
}

/**
Expand All @@ -39,6 +42,10 @@ export interface TracingService<T extends TracingSnapshot> {
* used when additional work is performed that was scheduled in this context.
*
* @param linkedSnapshot Optional snapshot to use link to the current context.
* The caller is no longer responsible for calling dispose on the linkedSnapshot.
*
* @return The tracing snapshot. The caller is responsible for diposing of the
* snapshot.
*/
snapshot(linkedSnapshot: T | null): T;
}
1 change: 1 addition & 0 deletions packages/core/src/render3/after_render/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ export class AfterRenderSequence implements AfterRenderRef {
// associates the initial run of the hook with the context that created it.
// Follow-up runs are independent of that initial context and have different
// triggers.
this.snapshot?.dispose();
this.snapshot = null;
}

Expand Down
1 change: 1 addition & 0 deletions packages/core/test/acceptance/tracing_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ describe('TracingService', () => {
actions.push(action);
return fn();
},
dispose() {},
};
mockTracingService = {
snapshot: jasmine.createSpy('snapshot').and.returnValue(fakeSnapshot),
Expand Down

0 comments on commit 4792db9

Please sign in to comment.