-
Notifications
You must be signed in to change notification settings - Fork 26.4k
fix(zone.js): setTimeout patch should clean tasksByHandleId cache #40586
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- I have updated the PR text for grammar. Please update the commit message to match.
- The change seems reasonable, but it needs a test. Could you add one.
a00971d
to
29e0a7a
Compare
@mhevery , thanks for the review, I have updated the commit message, but since this |
2faa5ad
to
098bf71
Compare
I don't think you need to have |
@mhevery , yeah, I understand your point, now most cases behave correctly even the |
Close angular#40387 Currently zone.js patches `setTimeout` and keeps a `tasksByHandleId` map to keep `timerId` <-> `ZoneTask` relationship. This is needed so that when `clearTimeout(timerId)` is called, zone.js can find the associated `ZoneTask`. Now zone.js set the `tasksByHandleId` map in the `scheduleTask` function, but if the `setTimeout` is running in the `FakeAsyncZoneSpec` or any other `ZoneSpec` with `onScheduleTask` hooks. The `scheduleTask` in `timer` patch may not be invoked. For example: ``` fakeAsync(() => { setTimeout(() => {}); tick(); }); ``` In this case, the `timerId` kept in the `tasksByHandleId` map is not cleared. This is because the `FakeAsyncZoneSpec` in the `onScheduleTask` hook looks like this. ``` onScheduleTask(delegate, ..., task) { fakeAsyncScheduler.setTimeout(task); return task; } ``` Because `FakeAsyncZoneSpec` handles the task itself and it doesn't call `parentDelegate.onScheduleTask`, therefore the default `scheduleTask` in the `timer` patch is not invoked. In this commit, the cleanup logic is moved from `scheduleTask` to `setTimeout` patch entry to avoid the memory leak.
098bf71
to
be04789
Compare
@mhevery , I have added one test case to describe the fix, so this issue will only cause memory leak when using |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Close #40387
Currently zone.js patches
setTimeout
and keeps atasksByHandleId
map to keeptimerId
<->ZoneTask
relationship. This is needed so that whenclearTimeout(timerId)
is called, zone.js can find the associatedZoneTask
. Now zone.js set thetasksByHandleId
map in thescheduleTask
function, but if thesetTimeout
is running in theFakeAsyncZoneSpec
or any otherZoneSpec
withonScheduleTask
hooks. ThescheduleTask
intimer
patch may not be invoked.For example:
In this case, the
timerId
kept in thetasksByHandleId
map is not cleared.This is because the
FakeAsyncZoneSpec
in theonScheduleTask
hook looks like this.Because
FakeAsyncZoneSpec
handles the task itself and it doesn't callparentDelegate.onScheduleTask
,therefore the default
scheduleTask
in thetimer
patch is not invoked.In this commit, the cleanup logic is moved from
scheduleTask
tosetTimeout
patch entry toavoid the memory leak.