@samitouri / QOS-React-2 / commits / 36df483af4

Add feature flag to disable scheduler timeout in work loop (#19771)

Ricky committed Sep 4, 2020 at 10:58 UTC 36df483af4a626fd4021c060fcb0f62471e82af1
12 files changed +39 -2
packages/react-reconciler/src/ReactFiberWorkLoop.new.js
+14 -1
@@ -30,6 +30,7 @@ import {
30 enableSchedulingProfiler,
31 enableScopeAPI,
32 skipUnmountedBoundaries,
33 + disableSchedulerTimeoutInWorkLoop,
34 } from 'shared/ReactFeatureFlags';
35 import ReactSharedInternals from 'shared/ReactSharedInternals';
36 import invariant from 'shared/invariant';
@@ -750,7 +751,7 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
751
752 // This is the entry point for every concurrent task, i.e. anything that
753 // goes through Scheduler.
753 -function performConcurrentWorkOnRoot(root) {
754 +function performConcurrentWorkOnRoot(root, didTimeout) {
755 // Since we know we're in a React event, we can clear the current
756 // event time. The next update will compute a new event time.
757 currentEventTime = NoTimestamp;
@@ -790,6 +791,18 @@ function performConcurrentWorkOnRoot(root) {
791 return null;
792 }
793
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 +
806 let exitStatus = renderRootConcurrent(root, lanes);
807
808 if (
packages/react-reconciler/src/ReactFiberWorkLoop.old.js
+14 -1
@@ -30,6 +30,7 @@ import {
30 enableSchedulingProfiler,
31 enableScopeAPI,
32 skipUnmountedBoundaries,
33 + disableSchedulerTimeoutInWorkLoop,
34 } from 'shared/ReactFeatureFlags';
35 import ReactSharedInternals from 'shared/ReactSharedInternals';
36 import invariant from 'shared/invariant';
@@ -738,7 +739,7 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
739
740 // This is the entry point for every concurrent task, i.e. anything that
741 // goes through Scheduler.
741 -function performConcurrentWorkOnRoot(root) {
742 +function performConcurrentWorkOnRoot(root, didTimeout) {
743 // Since we know we're in a React event, we can clear the current
744 // event time. The next update will compute a new event time.
745 currentEventTime = NoTimestamp;
@@ -778,6 +779,18 @@ function performConcurrentWorkOnRoot(root) {
779 return null;
780 }
781
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 +
794 let exitStatus = renderRootConcurrent(root, lanes);
795
796 if (
packages/shared/ReactFeatureFlags.js
+2
@@ -137,3 +137,5 @@ export const enableDiscreteEventFlushingChange = false;
137 export const enablePassiveEventIntervention = true;
138
139 export const enableEagerRootListeners = true;
140 +
141 +export const disableSchedulerTimeoutInWorkLoop = false;
packages/shared/forks/ReactFeatureFlags.native-fb.js
+1
@@ -51,6 +51,7 @@ export const decoupleUpdatePriorityFromScheduler = false;
51 export const enableDiscreteEventFlushingChange = false;
52 export const enablePassiveEventIntervention = true;
53 export const enableEagerRootListeners = true;
54 +export const disableSchedulerTimeoutInWorkLoop = false;
55
56 // Flow magic to verify the exports of this file match the original version.
57 // eslint-disable-next-line no-unused-vars
packages/shared/forks/ReactFeatureFlags.native-oss.js
+1
@@ -50,6 +50,7 @@ export const decoupleUpdatePriorityFromScheduler = false;
50 export const enableDiscreteEventFlushingChange = false;
51 export const enablePassiveEventIntervention = true;
52 export const enableEagerRootListeners = true;
53 +export const disableSchedulerTimeoutInWorkLoop = false;
54
55 // Flow magic to verify the exports of this file match the original version.
56 // eslint-disable-next-line no-unused-vars
packages/shared/forks/ReactFeatureFlags.test-renderer.js
+1
@@ -50,6 +50,7 @@ export const decoupleUpdatePriorityFromScheduler = false;
50 export const enableDiscreteEventFlushingChange = false;
51 export const enablePassiveEventIntervention = true;
52 export const enableEagerRootListeners = true;
53 +export const disableSchedulerTimeoutInWorkLoop = false;
54
55 // Flow magic to verify the exports of this file match the original version.
56 // eslint-disable-next-line no-unused-vars
packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
+1
@@ -50,6 +50,7 @@ export const decoupleUpdatePriorityFromScheduler = false;
50 export const enableDiscreteEventFlushingChange = false;
51 export const enablePassiveEventIntervention = true;
52 export const enableEagerRootListeners = true;
53 +export const disableSchedulerTimeoutInWorkLoop = false;
54
55 // Flow magic to verify the exports of this file match the original version.
56 // eslint-disable-next-line no-unused-vars
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+1
@@ -50,6 +50,7 @@ export const decoupleUpdatePriorityFromScheduler = false;
50 export const enableDiscreteEventFlushingChange = false;
51 export const enablePassiveEventIntervention = true;
52 export const enableEagerRootListeners = true;
53 +export const disableSchedulerTimeoutInWorkLoop = false;
54
55 // Flow magic to verify the exports of this file match the original version.
56 // eslint-disable-next-line no-unused-vars
packages/shared/forks/ReactFeatureFlags.testing.js
+1
@@ -50,6 +50,7 @@ export const decoupleUpdatePriorityFromScheduler = false;
50 export const enableDiscreteEventFlushingChange = false;
51 export const enablePassiveEventIntervention = true;
52 export const enableEagerRootListeners = true;
53 +export const disableSchedulerTimeoutInWorkLoop = false;
54
55 // Flow magic to verify the exports of this file match the original version.
56 // eslint-disable-next-line no-unused-vars
packages/shared/forks/ReactFeatureFlags.testing.www.js
+1
@@ -50,6 +50,7 @@ export const decoupleUpdatePriorityFromScheduler = false;
50 export const enableDiscreteEventFlushingChange = true;
51 export const enablePassiveEventIntervention = true;
52 export const enableEagerRootListeners = true;
53 +export const disableSchedulerTimeoutInWorkLoop = false;
54
55 // Flow magic to verify the exports of this file match the original version.
56 // eslint-disable-next-line no-unused-vars
packages/shared/forks/ReactFeatureFlags.www-dynamic.js
+1
@@ -48,3 +48,4 @@ export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
48 // to __VARIANT__.
49 export const enableTrustedTypesIntegration = false;
50 export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
51 +export const disableSchedulerTimeoutInWorkLoop = __VARIANT__;
packages/shared/forks/ReactFeatureFlags.www.js
+1
@@ -29,6 +29,7 @@ export const {
29 skipUnmountedBoundaries,
30 enablePassiveEventIntervention,
31 enableEagerRootListeners,
32 + disableSchedulerTimeoutInWorkLoop,
33 } = dynamicFeatureFlags;
34
35 // On WWW, __EXPERIMENTAL__ is used for a new modern build.