From 11565a207cca98daa57a57253745e6aa866c9a6f Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Wed, 6 Feb 2019 17:16:39 +0000 Subject: [PATCH] Revert "Scheduler.unstable_next (#14756)" This reverts commit bc9818f24d55e681aea39ecae59b8f544318169d. --- .../src/__tests__/ReactCache-test.internal.js | 22 --- .../src/ReactFiberScheduler.js | 148 +++++++++--------- packages/react/src/ReactSharedInternals.js | 2 - .../npm/umd/scheduler.development.js | 8 - .../npm/umd/scheduler.production.min.js | 8 - .../npm/umd/scheduler.profiling.min.js | 8 - packages/scheduler/src/Scheduler.js | 32 ---- packages/shared/forks/Scheduler.umd.js | 16 -- 8 files changed, 78 insertions(+), 166 deletions(-) diff --git a/packages/react-cache/src/__tests__/ReactCache-test.internal.js b/packages/react-cache/src/__tests__/ReactCache-test.internal.js index 36a6f0f84744b..e87d53e063c40 100644 --- a/packages/react-cache/src/__tests__/ReactCache-test.internal.js +++ b/packages/react-cache/src/__tests__/ReactCache-test.internal.js @@ -24,8 +24,6 @@ describe('ReactCache', () => { beforeEach(() => { jest.resetModules(); - let currentPriorityLevel = 3; - jest.mock('scheduler', () => { let callbacks = []; return { @@ -40,26 +38,6 @@ describe('ReactCache', () => { callback(); } }, - - unstable_ImmediatePriority: 1, - unstable_UserBlockingPriority: 2, - unstable_NormalPriority: 3, - unstable_LowPriority: 4, - unstable_IdlePriority: 5, - - unstable_runWithPriority(priorityLevel, fn) { - const prevPriorityLevel = currentPriorityLevel; - currentPriorityLevel = priorityLevel; - try { - return fn(); - } finally { - currentPriorityLevel = prevPriorityLevel; - } - }, - - unstable_getCurrentPriorityLevel() { - return currentPriorityLevel; - }, }; }); diff --git a/packages/react-reconciler/src/ReactFiberScheduler.js b/packages/react-reconciler/src/ReactFiberScheduler.js index baa100f0d266a..5712dbc9cd6d1 100644 --- a/packages/react-reconciler/src/ReactFiberScheduler.js +++ b/packages/react-reconciler/src/ReactFiberScheduler.js @@ -15,18 +15,8 @@ import type {Interaction} from 'scheduler/src/Tracing'; import { __interactionsRef, __subscriberRef, - unstable_wrap as Scheduler_tracing_wrap, + unstable_wrap as Schedule_tracing_wrap, } from 'scheduler/tracing'; -import { - unstable_next as Scheduler_next, - unstable_getCurrentPriorityLevel as getCurrentPriorityLevel, - unstable_runWithPriority as runWithPriority, - unstable_ImmediatePriority as ImmediatePriority, - unstable_UserBlockingPriority as UserBlockingPriority, - unstable_NormalPriority as NormalPriority, - unstable_LowPriority as LowPriority, - unstable_IdlePriority as IdlePriority, -} from 'scheduler'; import { invokeGuardedCallback, hasCaughtError, @@ -132,7 +122,7 @@ import { computeAsyncExpiration, computeInteractiveExpiration, } from './ReactFiberExpirationTime'; -import {ConcurrentMode, ProfileMode, NoContext} from './ReactTypeOfMode'; +import {ConcurrentMode, ProfileMode} from './ReactTypeOfMode'; import {enqueueUpdate, resetCurrentlyProcessingQueue} from './ReactUpdateQueue'; import {createCapturedValue} from './ReactCapturedValue'; import { @@ -252,6 +242,11 @@ if (__DEV__) { // Used to ensure computeUniqueAsyncExpiration is monotonically decreasing. let lastUniqueAsyncExpiration: number = Sync - 1; +// Represents the expiration time that incoming updates should use. (If this +// is NoWork, use the default strategy: async updates in async mode, sync +// updates in sync mode.) +let expirationContext: ExpirationTime = NoWork; + let isWorking: boolean = false; // The next work in progress fiber that we're currently working on. @@ -798,11 +793,9 @@ function commitRoot(root: FiberRoot, finishedWork: Fiber): void { // TODO: Avoid this extra callback by mutating the tracing ref directly, // like we do at the beginning of commitRoot. I've opted not to do that // here because that code is still in flux. - callback = Scheduler_tracing_wrap(callback); + callback = Schedule_tracing_wrap(callback); } - passiveEffectCallbackHandle = runWithPriority(NormalPriority, () => { - return schedulePassiveEffects(callback); - }); + passiveEffectCallbackHandle = schedulePassiveEffects(callback); passiveEffectCallback = callback; } @@ -1586,58 +1579,52 @@ function computeUniqueAsyncExpiration(): ExpirationTime { } function computeExpirationForFiber(currentTime: ExpirationTime, fiber: Fiber) { - const priorityLevel = getCurrentPriorityLevel(); - let expirationTime; - if ((fiber.mode & ConcurrentMode) === NoContext) { - // Outside of concurrent mode, updates are always synchronous. - expirationTime = Sync; - } else if (isWorking && !isCommitting) { - // During render phase, updates expire during as the current render. - expirationTime = nextRenderExpirationTime; + if (expirationContext !== NoWork) { + // An explicit expiration context was set; + expirationTime = expirationContext; + } else if (isWorking) { + if (isCommitting) { + // Updates that occur during the commit phase should have sync priority + // by default. + expirationTime = Sync; + } else { + // Updates during the render phase should expire at the same time as + // the work that is being rendered. + expirationTime = nextRenderExpirationTime; + } } else { - switch (priorityLevel) { - case ImmediatePriority: - expirationTime = Sync; - break; - case UserBlockingPriority: + // No explicit expiration context was set, and we're not currently + // performing work. Calculate a new expiration time. + if (fiber.mode & ConcurrentMode) { + if (isBatchingInteractiveUpdates) { + // This is an interactive update expirationTime = computeInteractiveExpiration(currentTime); - break; - case NormalPriority: - // This is a normal, concurrent update + } else { + // This is an async update expirationTime = computeAsyncExpiration(currentTime); - break; - case LowPriority: - case IdlePriority: - expirationTime = Never; - break; - default: - invariant( - false, - 'Unknown priority level. This error is likely caused by a bug in ' + - 'React. Please file an issue.', - ); - } - - // If we're in the middle of rendering a tree, do not update at the same - // expiration time that is already rendering. - if (nextRoot !== null && expirationTime === nextRenderExpirationTime) { - expirationTime -= 1; + } + // If we're in the middle of rendering a tree, do not update at the same + // expiration time that is already rendering. + if (nextRoot !== null && expirationTime === nextRenderExpirationTime) { + expirationTime -= 1; + } + } else { + // This is a sync update + expirationTime = Sync; } } - - // Keep track of the lowest pending interactive expiration time. This - // allows us to synchronously flush all interactive updates - // when needed. - // TODO: Move this to renderer? - if ( - priorityLevel === UserBlockingPriority && - (lowestPriorityPendingInteractiveExpirationTime === NoWork || - expirationTime < lowestPriorityPendingInteractiveExpirationTime) - ) { - lowestPriorityPendingInteractiveExpirationTime = expirationTime; + if (isBatchingInteractiveUpdates) { + // This is an interactive update. Keep track of the lowest pending + // interactive expiration time. This allows us to synchronously flush + // all interactive updates when needed. + if ( + lowestPriorityPendingInteractiveExpirationTime === NoWork || + expirationTime < lowestPriorityPendingInteractiveExpirationTime + ) { + lowestPriorityPendingInteractiveExpirationTime = expirationTime; + } } - return expirationTime; } @@ -1875,6 +1862,20 @@ function scheduleWork(fiber: Fiber, expirationTime: ExpirationTime) { } } +function deferredUpdates(fn: () => A): A { + const currentTime = requestCurrentTime(); + const previousExpirationContext = expirationContext; + const previousIsBatchingInteractiveUpdates = isBatchingInteractiveUpdates; + expirationContext = computeAsyncExpiration(currentTime); + isBatchingInteractiveUpdates = false; + try { + return fn(); + } finally { + expirationContext = previousExpirationContext; + isBatchingInteractiveUpdates = previousIsBatchingInteractiveUpdates; + } +} + function syncUpdates( fn: (A, B, C0, D) => R, a: A, @@ -1882,9 +1883,13 @@ function syncUpdates( c: C0, d: D, ): R { - return runWithPriority(ImmediatePriority, () => { + const previousExpirationContext = expirationContext; + expirationContext = Sync; + try { return fn(a, b, c, d); - }); + } finally { + expirationContext = previousExpirationContext; + } } // TODO: Everything below this is written as if it has been lifted to the @@ -1905,6 +1910,7 @@ let unhandledError: mixed | null = null; let isBatchingUpdates: boolean = false; let isUnbatchingUpdates: boolean = false; +let isBatchingInteractiveUpdates: boolean = false; let completedBatches: Array | null = null; @@ -2435,9 +2441,7 @@ function completeRoot( lastCommittedRootDuringThisBatch = root; nestedUpdateCount = 0; } - runWithPriority(ImmediatePriority, () => { - commitRoot(root, finishedWork); - }); + commitRoot(root, finishedWork); } function onUncaughtError(error: mixed) { @@ -2503,6 +2507,9 @@ function flushSync(fn: (a: A) => R, a: A): R { } function interactiveUpdates(fn: (A, B) => R, a: A, b: B): R { + if (isBatchingInteractiveUpdates) { + return fn(a, b); + } // If there are any pending interactive updates, synchronously flush them. // This needs to happen before we read any handlers, because the effect of // the previous event may influence which handlers are called during @@ -2516,13 +2523,14 @@ function interactiveUpdates(fn: (A, B) => R, a: A, b: B): R { performWork(lowestPriorityPendingInteractiveExpirationTime, false); lowestPriorityPendingInteractiveExpirationTime = NoWork; } + const previousIsBatchingInteractiveUpdates = isBatchingInteractiveUpdates; const previousIsBatchingUpdates = isBatchingUpdates; + isBatchingInteractiveUpdates = true; isBatchingUpdates = true; try { - return runWithPriority(UserBlockingPriority, () => { - return fn(a, b); - }); + return fn(a, b); } finally { + isBatchingInteractiveUpdates = previousIsBatchingInteractiveUpdates; isBatchingUpdates = previousIsBatchingUpdates; if (!isBatchingUpdates && !isRendering) { performSyncWork(); @@ -2572,7 +2580,7 @@ export { unbatchedUpdates, flushSync, flushControlled, - Scheduler_next as deferredUpdates, + deferredUpdates, syncUpdates, interactiveUpdates, flushInteractiveUpdates, diff --git a/packages/react/src/ReactSharedInternals.js b/packages/react/src/ReactSharedInternals.js index 1fe0c2391bd13..9cdce1891bc5c 100644 --- a/packages/react/src/ReactSharedInternals.js +++ b/packages/react/src/ReactSharedInternals.js @@ -12,7 +12,6 @@ import { unstable_now, unstable_scheduleCallback, unstable_runWithPriority, - unstable_next, unstable_getFirstCallbackNode, unstable_pauseExecution, unstable_continueExecution, @@ -54,7 +53,6 @@ if (__UMD__) { unstable_now, unstable_scheduleCallback, unstable_runWithPriority, - unstable_next, unstable_wrapCallback, unstable_getFirstCallbackNode, unstable_pauseExecution, diff --git a/packages/scheduler/npm/umd/scheduler.development.js b/packages/scheduler/npm/umd/scheduler.development.js index ac632eb288bff..41ac8e437bbd6 100644 --- a/packages/scheduler/npm/umd/scheduler.development.js +++ b/packages/scheduler/npm/umd/scheduler.development.js @@ -54,13 +54,6 @@ ); } - function unstable_next() { - return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_next.apply( - this, - arguments - ); - } - function unstable_wrapCallback() { return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_wrapCallback.apply( this, @@ -102,7 +95,6 @@ unstable_cancelCallback: unstable_cancelCallback, unstable_shouldYield: unstable_shouldYield, unstable_runWithPriority: unstable_runWithPriority, - unstable_next: unstable_next, unstable_wrapCallback: unstable_wrapCallback, unstable_getCurrentPriorityLevel: unstable_getCurrentPriorityLevel, unstable_continueExecution: unstable_continueExecution, diff --git a/packages/scheduler/npm/umd/scheduler.production.min.js b/packages/scheduler/npm/umd/scheduler.production.min.js index da2aefa9e4bf1..cea54f4da3cba 100644 --- a/packages/scheduler/npm/umd/scheduler.production.min.js +++ b/packages/scheduler/npm/umd/scheduler.production.min.js @@ -54,13 +54,6 @@ ); } - function unstable_next() { - return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_next.apply( - this, - arguments - ); - } - function unstable_wrapCallback() { return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_wrapCallback.apply( this, @@ -96,7 +89,6 @@ unstable_cancelCallback: unstable_cancelCallback, unstable_shouldYield: unstable_shouldYield, unstable_runWithPriority: unstable_runWithPriority, - unstable_next: unstable_next, unstable_wrapCallback: unstable_wrapCallback, unstable_getCurrentPriorityLevel: unstable_getCurrentPriorityLevel, unstable_continueExecution: unstable_continueExecution, diff --git a/packages/scheduler/npm/umd/scheduler.profiling.min.js b/packages/scheduler/npm/umd/scheduler.profiling.min.js index da2aefa9e4bf1..cea54f4da3cba 100644 --- a/packages/scheduler/npm/umd/scheduler.profiling.min.js +++ b/packages/scheduler/npm/umd/scheduler.profiling.min.js @@ -54,13 +54,6 @@ ); } - function unstable_next() { - return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_next.apply( - this, - arguments - ); - } - function unstable_wrapCallback() { return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_wrapCallback.apply( this, @@ -96,7 +89,6 @@ unstable_cancelCallback: unstable_cancelCallback, unstable_shouldYield: unstable_shouldYield, unstable_runWithPriority: unstable_runWithPriority, - unstable_next: unstable_next, unstable_wrapCallback: unstable_wrapCallback, unstable_getCurrentPriorityLevel: unstable_getCurrentPriorityLevel, unstable_continueExecution: unstable_continueExecution, diff --git a/packages/scheduler/src/Scheduler.js b/packages/scheduler/src/Scheduler.js index df1e9b3bdada0..a6e27850dab71 100644 --- a/packages/scheduler/src/Scheduler.js +++ b/packages/scheduler/src/Scheduler.js @@ -264,37 +264,6 @@ function unstable_runWithPriority(priorityLevel, eventHandler) { } } -function unstable_next(eventHandler) { - let priorityLevel; - switch (currentPriorityLevel) { - case ImmediatePriority: - case UserBlockingPriority: - case NormalPriority: - // Shift down to normal priority - priorityLevel = NormalPriority; - break; - default: - // Anything lower than normal priority should remain at the current level. - priorityLevel = currentPriorityLevel; - break; - } - - var previousPriorityLevel = currentPriorityLevel; - var previousEventStartTime = currentEventStartTime; - currentPriorityLevel = priorityLevel; - currentEventStartTime = getCurrentTime(); - - try { - return eventHandler(); - } finally { - currentPriorityLevel = previousPriorityLevel; - currentEventStartTime = previousEventStartTime; - - // Before exiting, flush all the immediate work that was scheduled. - flushImmediateWork(); - } -} - function unstable_wrapCallback(callback) { var parentPriorityLevel = currentPriorityLevel; return function() { @@ -719,7 +688,6 @@ export { IdlePriority as unstable_IdlePriority, LowPriority as unstable_LowPriority, unstable_runWithPriority, - unstable_next, unstable_scheduleCallback, unstable_cancelCallback, unstable_wrapCallback, diff --git a/packages/shared/forks/Scheduler.umd.js b/packages/shared/forks/Scheduler.umd.js index 6c9c918dc8779..c33b2d0667416 100644 --- a/packages/shared/forks/Scheduler.umd.js +++ b/packages/shared/forks/Scheduler.umd.js @@ -17,16 +17,8 @@ const { unstable_scheduleCallback, unstable_shouldYield, unstable_getFirstCallbackNode, - unstable_runWithPriority, - unstable_next, unstable_continueExecution, unstable_pauseExecution, - unstable_getCurrentPriorityLevel, - unstable_ImmediatePriority, - unstable_UserBlockingPriority, - unstable_NormalPriority, - unstable_LowPriority, - unstable_IdlePriority, } = ReactInternals.Scheduler; export { @@ -35,14 +27,6 @@ export { unstable_scheduleCallback, unstable_shouldYield, unstable_getFirstCallbackNode, - unstable_runWithPriority, - unstable_next, unstable_continueExecution, unstable_pauseExecution, - unstable_getCurrentPriorityLevel, - unstable_ImmediatePriority, - unstable_UserBlockingPriority, - unstable_NormalPriority, - unstable_LowPriority, - unstable_IdlePriority, };