Skip to content

Commit 36df483

Browse files
authored
Add feature flag to disable scheduler timeout in work loop (#19771)
1 parent eabd18c commit 36df483

12 files changed

+39
-2
lines changed

packages/react-reconciler/src/ReactFiberWorkLoop.new.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
enableSchedulingProfiler,
3131
enableScopeAPI,
3232
skipUnmountedBoundaries,
33+
disableSchedulerTimeoutInWorkLoop,
3334
} from 'shared/ReactFeatureFlags';
3435
import ReactSharedInternals from 'shared/ReactSharedInternals';
3536
import invariant from 'shared/invariant';
@@ -750,7 +751,7 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
750751

751752
// This is the entry point for every concurrent task, i.e. anything that
752753
// goes through Scheduler.
753-
function performConcurrentWorkOnRoot(root) {
754+
function performConcurrentWorkOnRoot(root, didTimeout) {
754755
// Since we know we're in a React event, we can clear the current
755756
// event time. The next update will compute a new event time.
756757
currentEventTime = NoTimestamp;
@@ -790,6 +791,18 @@ function performConcurrentWorkOnRoot(root) {
790791
return null;
791792
}
792793

794+
// TODO: We only check `didTimeout` defensively, to account for a Scheduler
795+
// bug we're still investigating. Once the bug in Scheduler is fixed,
796+
// we can remove this, since we track expiration ourselves.
797+
if (!disableSchedulerTimeoutInWorkLoop && didTimeout) {
798+
// Something expired. Flush synchronously until there's no expired
799+
// work left.
800+
markRootExpired(root, lanes);
801+
// This will schedule a synchronous callback.
802+
ensureRootIsScheduled(root, now());
803+
return null;
804+
}
805+
793806
let exitStatus = renderRootConcurrent(root, lanes);
794807

795808
if (

packages/react-reconciler/src/ReactFiberWorkLoop.old.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
enableSchedulingProfiler,
3131
enableScopeAPI,
3232
skipUnmountedBoundaries,
33+
disableSchedulerTimeoutInWorkLoop,
3334
} from 'shared/ReactFeatureFlags';
3435
import ReactSharedInternals from 'shared/ReactSharedInternals';
3536
import invariant from 'shared/invariant';
@@ -738,7 +739,7 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
738739

739740
// This is the entry point for every concurrent task, i.e. anything that
740741
// goes through Scheduler.
741-
function performConcurrentWorkOnRoot(root) {
742+
function performConcurrentWorkOnRoot(root, didTimeout) {
742743
// Since we know we're in a React event, we can clear the current
743744
// event time. The next update will compute a new event time.
744745
currentEventTime = NoTimestamp;
@@ -778,6 +779,18 @@ function performConcurrentWorkOnRoot(root) {
778779
return null;
779780
}
780781

782+
// TODO: We only check `didTimeout` defensively, to account for a Scheduler
783+
// bug we're still investigating. Once the bug in Scheduler is fixed,
784+
// we can remove this, since we track expiration ourselves.
785+
if (!disableSchedulerTimeoutInWorkLoop && didTimeout) {
786+
// Something expired. Flush synchronously until there's no expired
787+
// work left.
788+
markRootExpired(root, lanes);
789+
// This will schedule a synchronous callback.
790+
ensureRootIsScheduled(root, now());
791+
return null;
792+
}
793+
781794
let exitStatus = renderRootConcurrent(root, lanes);
782795

783796
if (

packages/shared/ReactFeatureFlags.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,5 @@ export const enableDiscreteEventFlushingChange = false;
137137
export const enablePassiveEventIntervention = true;
138138

139139
export const enableEagerRootListeners = true;
140+
141+
export const disableSchedulerTimeoutInWorkLoop = false;

packages/shared/forks/ReactFeatureFlags.native-fb.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export const decoupleUpdatePriorityFromScheduler = false;
5151
export const enableDiscreteEventFlushingChange = false;
5252
export const enablePassiveEventIntervention = true;
5353
export const enableEagerRootListeners = true;
54+
export const disableSchedulerTimeoutInWorkLoop = false;
5455

5556
// Flow magic to verify the exports of this file match the original version.
5657
// eslint-disable-next-line no-unused-vars

packages/shared/forks/ReactFeatureFlags.native-oss.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export const decoupleUpdatePriorityFromScheduler = false;
5050
export const enableDiscreteEventFlushingChange = false;
5151
export const enablePassiveEventIntervention = true;
5252
export const enableEagerRootListeners = true;
53+
export const disableSchedulerTimeoutInWorkLoop = false;
5354

5455
// Flow magic to verify the exports of this file match the original version.
5556
// eslint-disable-next-line no-unused-vars

packages/shared/forks/ReactFeatureFlags.test-renderer.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export const decoupleUpdatePriorityFromScheduler = false;
5050
export const enableDiscreteEventFlushingChange = false;
5151
export const enablePassiveEventIntervention = true;
5252
export const enableEagerRootListeners = true;
53+
export const disableSchedulerTimeoutInWorkLoop = false;
5354

5455
// Flow magic to verify the exports of this file match the original version.
5556
// eslint-disable-next-line no-unused-vars

packages/shared/forks/ReactFeatureFlags.test-renderer.native.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export const decoupleUpdatePriorityFromScheduler = false;
5050
export const enableDiscreteEventFlushingChange = false;
5151
export const enablePassiveEventIntervention = true;
5252
export const enableEagerRootListeners = true;
53+
export const disableSchedulerTimeoutInWorkLoop = false;
5354

5455
// Flow magic to verify the exports of this file match the original version.
5556
// eslint-disable-next-line no-unused-vars

packages/shared/forks/ReactFeatureFlags.test-renderer.www.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export const decoupleUpdatePriorityFromScheduler = false;
5050
export const enableDiscreteEventFlushingChange = false;
5151
export const enablePassiveEventIntervention = true;
5252
export const enableEagerRootListeners = true;
53+
export const disableSchedulerTimeoutInWorkLoop = false;
5354

5455
// Flow magic to verify the exports of this file match the original version.
5556
// eslint-disable-next-line no-unused-vars

packages/shared/forks/ReactFeatureFlags.testing.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export const decoupleUpdatePriorityFromScheduler = false;
5050
export const enableDiscreteEventFlushingChange = false;
5151
export const enablePassiveEventIntervention = true;
5252
export const enableEagerRootListeners = true;
53+
export const disableSchedulerTimeoutInWorkLoop = false;
5354

5455
// Flow magic to verify the exports of this file match the original version.
5556
// eslint-disable-next-line no-unused-vars

packages/shared/forks/ReactFeatureFlags.testing.www.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export const decoupleUpdatePriorityFromScheduler = false;
5050
export const enableDiscreteEventFlushingChange = true;
5151
export const enablePassiveEventIntervention = true;
5252
export const enableEagerRootListeners = true;
53+
export const disableSchedulerTimeoutInWorkLoop = false;
5354

5455
// Flow magic to verify the exports of this file match the original version.
5556
// eslint-disable-next-line no-unused-vars

packages/shared/forks/ReactFeatureFlags.www-dynamic.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,4 @@ export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
4848
// to __VARIANT__.
4949
export const enableTrustedTypesIntegration = false;
5050
export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
51+
export const disableSchedulerTimeoutInWorkLoop = __VARIANT__;

packages/shared/forks/ReactFeatureFlags.www.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export const {
2929
skipUnmountedBoundaries,
3030
enablePassiveEventIntervention,
3131
enableEagerRootListeners,
32+
disableSchedulerTimeoutInWorkLoop,
3233
} = dynamicFeatureFlags;
3334

3435
// On WWW, __EXPERIMENTAL__ is used for a new modern build.

0 commit comments

Comments
 (0)