fix(scheduler): prevent duplicate jobs being queued (#11826)

Fix #11712
Fix #11807
This commit is contained in:
skirtle 2024-09-05 13:51:26 +01:00 committed by GitHub
parent e84c4a608e
commit df56cc5287
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 20 additions and 6 deletions

View File

@ -108,9 +108,8 @@ export function queueJob(job: SchedulerJob): void {
queue.splice(findInsertionIndex(jobId), 0, job) queue.splice(findInsertionIndex(jobId), 0, job)
} }
if (!(job.flags! & SchedulerJobFlags.ALLOW_RECURSE)) {
job.flags! |= SchedulerJobFlags.QUEUED job.flags! |= SchedulerJobFlags.QUEUED
}
queueFlush() queueFlush()
} }
} }
@ -128,10 +127,8 @@ export function queuePostFlushCb(cb: SchedulerJobs): void {
activePostFlushCbs.splice(postFlushIndex + 1, 0, cb) activePostFlushCbs.splice(postFlushIndex + 1, 0, cb)
} else if (!(cb.flags! & SchedulerJobFlags.QUEUED)) { } else if (!(cb.flags! & SchedulerJobFlags.QUEUED)) {
pendingPostFlushCbs.push(cb) pendingPostFlushCbs.push(cb)
if (!(cb.flags! & SchedulerJobFlags.ALLOW_RECURSE)) {
cb.flags! |= SchedulerJobFlags.QUEUED cb.flags! |= SchedulerJobFlags.QUEUED
} }
}
} else { } else {
// if cb is an array, it is a component lifecycle hook which can only be // if cb is an array, it is a component lifecycle hook which can only be
// triggered by a job, which is already deduped in the main queue, so // triggered by a job, which is already deduped in the main queue, so
@ -161,6 +158,9 @@ export function flushPreFlushCbs(
} }
queue.splice(i, 1) queue.splice(i, 1)
i-- i--
if (cb.flags! & SchedulerJobFlags.ALLOW_RECURSE) {
cb.flags! &= ~SchedulerJobFlags.QUEUED
}
cb() cb()
cb.flags! &= ~SchedulerJobFlags.QUEUED cb.flags! &= ~SchedulerJobFlags.QUEUED
} }
@ -194,6 +194,9 @@ export function flushPostFlushCbs(seen?: CountMap): void {
if (__DEV__ && checkRecursiveUpdates(seen!, cb)) { if (__DEV__ && checkRecursiveUpdates(seen!, cb)) {
continue continue
} }
if (cb.flags! & SchedulerJobFlags.ALLOW_RECURSE) {
cb.flags! &= ~SchedulerJobFlags.QUEUED
}
if (!(cb.flags! & SchedulerJobFlags.DISPOSED)) cb() if (!(cb.flags! & SchedulerJobFlags.DISPOSED)) cb()
cb.flags! &= ~SchedulerJobFlags.QUEUED cb.flags! &= ~SchedulerJobFlags.QUEUED
} }
@ -228,6 +231,9 @@ function flushJobs(seen?: CountMap) {
if (__DEV__ && check(job)) { if (__DEV__ && check(job)) {
continue continue
} }
if (job.flags! & SchedulerJobFlags.ALLOW_RECURSE) {
job.flags! &= ~SchedulerJobFlags.QUEUED
}
callWithErrorHandling( callWithErrorHandling(
job, job,
job.i, job.i,
@ -237,6 +243,14 @@ function flushJobs(seen?: CountMap) {
} }
} }
} finally { } finally {
// If there was an error we still need to clear the QUEUED flags
for (; flushIndex < queue.length; flushIndex++) {
const job = queue[flushIndex]
if (job) {
job.flags! &= ~SchedulerJobFlags.QUEUED
}
}
flushIndex = 0 flushIndex = 0
queue.length = 0 queue.length = 0