From 0e29c9d30809ceff8f6a3686426aa695e238e78c Mon Sep 17 00:00:00 2001 From: Jan Kassens Date: Fri, 8 Dec 2023 15:53:55 -0500 Subject: [PATCH] Move expiration times into FeatureFlags --- .../react-reconciler/src/ReactFiberLane.js | 11 +++++--- .../scheduler/src/SchedulerFeatureFlags.js | 4 +++ packages/scheduler/src/forks/Scheduler.js | 27 +++++++++---------- .../SchedulerFeatureFlags.www-dynamic.js | 4 +++ .../src/forks/SchedulerFeatureFlags.www.js | 12 ++++++--- packages/shared/ReactFeatureFlags.js | 3 +++ .../forks/ReactFeatureFlags.native-fb.js | 4 +++ .../forks/ReactFeatureFlags.native-oss.js | 4 +++ .../forks/ReactFeatureFlags.test-renderer.js | 4 +++ .../ReactFeatureFlags.test-renderer.native.js | 4 +++ .../ReactFeatureFlags.test-renderer.www.js | 4 +++ .../forks/ReactFeatureFlags.www-dynamic.js | 4 +++ .../shared/forks/ReactFeatureFlags.www.js | 3 +++ 13 files changed, 68 insertions(+), 20 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberLane.js b/packages/react-reconciler/src/ReactFiberLane.js index c110b29c250ef..7e056f2e71068 100644 --- a/packages/react-reconciler/src/ReactFiberLane.js +++ b/packages/react-reconciler/src/ReactFiberLane.js @@ -25,6 +25,9 @@ import { enableTransitionTracing, enableUnifiedSyncLane, enableUpdaterTracking, + syncLaneExpirationMs, + transitionLaneExpirationMs, + retryLaneExpirationMs, } from 'shared/ReactFeatureFlags'; import {isDevToolsPresent} from './ReactFiberDevToolsHook'; import {ConcurrentUpdatesByDefaultMode, NoMode} from './ReactTypeOfMode'; @@ -355,7 +358,7 @@ function computeExpirationTime(lane: Lane, currentTime: number) { // to fix the starvation. However, this scenario supports the idea that // expiration times are an important safeguard when starvation // does happen. - return currentTime + 250; + return currentTime + syncLaneExpirationMs; case DefaultHydrationLane: case DefaultLane: case TransitionHydrationLane: @@ -374,7 +377,7 @@ function computeExpirationTime(lane: Lane, currentTime: number) { case TransitionLane13: case TransitionLane14: case TransitionLane15: - return currentTime + 5000; + return currentTime + transitionLaneExpirationMs; case RetryLane1: case RetryLane2: case RetryLane3: @@ -384,7 +387,9 @@ function computeExpirationTime(lane: Lane, currentTime: number) { // crashes. There must be some other underlying bug; not super urgent but // ideally should figure out why and fix it. Unfortunately we don't have // a repro for the crashes, only detected via production metrics. - return enableRetryLaneExpiration ? currentTime + 5000 : NoTimestamp; + return enableRetryLaneExpiration + ? currentTime + retryLaneExpirationMs + : NoTimestamp; case SelectiveHydrationLane: case IdleHydrationLane: case IdleLane: diff --git a/packages/scheduler/src/SchedulerFeatureFlags.js b/packages/scheduler/src/SchedulerFeatureFlags.js index 182093a93c85c..5d207922ca968 100644 --- a/packages/scheduler/src/SchedulerFeatureFlags.js +++ b/packages/scheduler/src/SchedulerFeatureFlags.js @@ -14,3 +14,7 @@ export const enableIsInputPendingContinuous = false; export const frameYieldMs = 5; export const continuousYieldMs = 50; export const maxYieldMs = 300; + +export const userBlockingPriorityTimeout = 250; +export const normalPriorityTimeout = 5000; +export const lowPriorityTimeout = 10000; diff --git a/packages/scheduler/src/forks/Scheduler.js b/packages/scheduler/src/forks/Scheduler.js index 2263b706aad35..e4eb17b37a2c9 100644 --- a/packages/scheduler/src/forks/Scheduler.js +++ b/packages/scheduler/src/forks/Scheduler.js @@ -19,6 +19,9 @@ import { frameYieldMs, continuousYieldMs, maxYieldMs, + userBlockingPriorityTimeout, + lowPriorityTimeout, + normalPriorityTimeout, } from '../SchedulerFeatureFlags'; import {push, pop, peek} from '../SchedulerMinHeap'; @@ -75,15 +78,6 @@ if (hasPerformanceNow) { // 0b111111111111111111111111111111 var maxSigned31BitInt = 1073741823; -// Times out immediately -var IMMEDIATE_PRIORITY_TIMEOUT = -1; -// Eventually times out -var USER_BLOCKING_PRIORITY_TIMEOUT = 250; -var NORMAL_PRIORITY_TIMEOUT = 5000; -var LOW_PRIORITY_TIMEOUT = 10000; -// Never times out -var IDLE_PRIORITY_TIMEOUT = maxSigned31BitInt; - // Tasks are stored on a min heap var taskQueue: Array = []; var timerQueue: Array = []; @@ -362,20 +356,25 @@ function unstable_scheduleCallback( var timeout; switch (priorityLevel) { case ImmediatePriority: - timeout = IMMEDIATE_PRIORITY_TIMEOUT; + // Times out immediately + timeout = -1; break; case UserBlockingPriority: - timeout = USER_BLOCKING_PRIORITY_TIMEOUT; + // Eventually times out + timeout = userBlockingPriorityTimeout; break; case IdlePriority: - timeout = IDLE_PRIORITY_TIMEOUT; + // Never times out + timeout = maxSigned31BitInt; break; case LowPriority: - timeout = LOW_PRIORITY_TIMEOUT; + // Eventually times out + timeout = lowPriorityTimeout; break; case NormalPriority: default: - timeout = NORMAL_PRIORITY_TIMEOUT; + // Eventually times out + timeout = normalPriorityTimeout; break; } diff --git a/packages/scheduler/src/forks/SchedulerFeatureFlags.www-dynamic.js b/packages/scheduler/src/forks/SchedulerFeatureFlags.www-dynamic.js index 8232400b84d32..25d88aa4b903d 100644 --- a/packages/scheduler/src/forks/SchedulerFeatureFlags.www-dynamic.js +++ b/packages/scheduler/src/forks/SchedulerFeatureFlags.www-dynamic.js @@ -12,3 +12,7 @@ // with the __VARIANT__ set to `true`, and once set to `false`. export const enableProfiling = __VARIANT__; + +export const userBlockingPriorityTimeout = 250; +export const normalPriorityTimeout = 5000; +export const lowPriorityTimeout = 10000; diff --git a/packages/scheduler/src/forks/SchedulerFeatureFlags.www.js b/packages/scheduler/src/forks/SchedulerFeatureFlags.www.js index 4ad93cb70e594..a0713261db996 100644 --- a/packages/scheduler/src/forks/SchedulerFeatureFlags.www.js +++ b/packages/scheduler/src/forks/SchedulerFeatureFlags.www.js @@ -7,10 +7,16 @@ * @flow */ -const {enableProfiling: enableProfilingFeatureFlag} = - // $FlowFixMe[cannot-resolve-module] - require('SchedulerFeatureFlags'); +// $FlowFixMe[cannot-resolve-module] +const dynamicFeatureFlags = require('SchedulerFeatureFlags'); +const {enableProfiling: enableProfilingFeatureFlag} = dynamicFeatureFlags; + +export const { + userBlockingPriorityTimeout, + normalPriorityTimeout, + lowPriorityTimeout, +} = dynamicFeatureFlags; export const enableSchedulerDebugging = true; export const enableProfiling: boolean = __PROFILE__ && enableProfilingFeatureFlag; diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index 2ede92b1c06e0..acf2e6e9b9dcc 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -130,6 +130,9 @@ export const enableUseDeferredValueInitialArg = __EXPERIMENTAL__; * Enables an expiration time for retry lanes to avoid starvation. */ export const enableRetryLaneExpiration = false; +export const retryLaneExpirationMs = 5000; +export const syncLaneExpirationMs = 250; +export const transitionLaneExpirationMs = 5000; // ----------------------------------------------------------------------------- // Chopping Block diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index c293ebafd6d0b..8c8ff2cbf97bb 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -66,7 +66,11 @@ export const enableComponentStackLocations = false; export const enableLegacyFBSupport = false; export const enableFilterEmptyStringAttributesDOM = false; export const enableGetInspectorDataForInstanceInProduction = true; + export const enableRetryLaneExpiration = false; +export const retryLaneExpirationMs = 5000; +export const syncLaneExpirationMs = 250; +export const transitionLaneExpirationMs = 5000; export const createRootStrictEffectsByDefault = false; diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index b8203b3b3cbcb..795fab334ee80 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -49,7 +49,11 @@ export const enableComponentStackLocations = false; export const enableLegacyFBSupport = false; export const enableFilterEmptyStringAttributesDOM = false; export const enableGetInspectorDataForInstanceInProduction = false; + export const enableRetryLaneExpiration = false; +export const retryLaneExpirationMs = 5000; +export const syncLaneExpirationMs = 250; +export const transitionLaneExpirationMs = 5000; export const createRootStrictEffectsByDefault = false; export const enableUseRefAccessWarning = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index 611160e2a1f6a..e0216e3f57535 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -49,7 +49,11 @@ export const enableComponentStackLocations = true; export const enableLegacyFBSupport = false; export const enableFilterEmptyStringAttributesDOM = false; export const enableGetInspectorDataForInstanceInProduction = false; + export const enableRetryLaneExpiration = false; +export const retryLaneExpirationMs = 5000; +export const syncLaneExpirationMs = 250; +export const transitionLaneExpirationMs = 5000; export const createRootStrictEffectsByDefault = false; export const enableUseRefAccessWarning = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js index 60a15318c7c00..93d09f741601e 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js @@ -51,7 +51,11 @@ export const enableUseEffectEventHook = false; export const enableClientRenderFallbackOnTextMismatch = true; export const createRootStrictEffectsByDefault = false; export const enableUseRefAccessWarning = false; + export const enableRetryLaneExpiration = false; +export const retryLaneExpirationMs = 5000; +export const syncLaneExpirationMs = 250; +export const transitionLaneExpirationMs = 5000; export const disableSchedulerTimeoutInWorkLoop = false; export const enableLazyContextPropagation = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index c5678792313ae..d5fa0454eaaf0 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -49,7 +49,11 @@ export const enableComponentStackLocations = true; export const enableLegacyFBSupport = false; export const enableFilterEmptyStringAttributesDOM = true; export const enableGetInspectorDataForInstanceInProduction = false; + export const enableRetryLaneExpiration = false; +export const retryLaneExpirationMs = 5000; +export const syncLaneExpirationMs = 250; +export const transitionLaneExpirationMs = 5000; export const createRootStrictEffectsByDefault = false; export const enableUseRefAccessWarning = false; diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js index b824c9ac8323c..74c0ab2f6f5fd 100644 --- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js @@ -29,7 +29,11 @@ export const enableAsyncActions = __VARIANT__; export const alwaysThrottleRetries = __VARIANT__; export const enableDO_NOT_USE_disableStrictPassiveEffect = __VARIANT__; export const enableUseDeferredValueInitialArg = __VARIANT__; + export const enableRetryLaneExpiration = __VARIANT__; +export const retryLaneExpirationMs = 5000; +export const syncLaneExpirationMs = 250; +export const transitionLaneExpirationMs = 5000; // Enable this flag to help with concurrent mode debugging. // It logs information to the console about React scheduling, rendering, and commit phases. diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index 9f7724d0771c0..a76277e43b864 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -33,6 +33,9 @@ export const { enableDO_NOT_USE_disableStrictPassiveEffect, disableSchedulerTimeoutInWorkLoop, enableUseDeferredValueInitialArg, + retryLaneExpirationMs, + syncLaneExpirationMs, + transitionLaneExpirationMs, } = dynamicFeatureFlags; // On WWW, __EXPERIMENTAL__ is used for a new modern build.