Skip to content

Commit

Permalink
Use Lane to track root callback priority (facebook#21089)
Browse files Browse the repository at this point in the history
Instead of LanePriority.

I'm removing all uses of LanePriority so I can delete it.
  • Loading branch information
acdlite authored and koto committed Jun 15, 2021
1 parent 68adbb0 commit dec2ae5
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 114 deletions.
42 changes: 1 addition & 41 deletions packages/react-reconciler/src/ReactFiberLane.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @flow
*/

import type {FiberRoot, ReactPriorityLevel} from './ReactInternalTypes';
import type {FiberRoot} from './ReactInternalTypes';

// TODO: Ideally these types would be opaque but that doesn't work well with
// our reconciler fork infra, since these leak into non-reconciler packages.
Expand Down Expand Up @@ -35,17 +35,8 @@ export type Lanes = number;
export type Lane = number;
export type LaneMap<T> = Array<T>;

import invariant from 'shared/invariant';
import {enableCache, enableSchedulingProfiler} from 'shared/ReactFeatureFlags';

import {
ImmediatePriority as ImmediateSchedulerPriority,
UserBlockingPriority as UserBlockingSchedulerPriority,
NormalPriority as NormalSchedulerPriority,
IdlePriority as IdleSchedulerPriority,
NoPriority as NoSchedulerPriority,
} from './SchedulerWithReactIntegration.new';

export const SyncLanePriority: LanePriority = 12;

const InputContinuousHydrationLanePriority: LanePriority = 11;
Expand Down Expand Up @@ -244,37 +235,6 @@ function getHighestPriorityLanes(lanes: Lanes | Lane): Lanes {
}
}

export function lanePriorityToSchedulerPriority(
lanePriority: LanePriority,
): ReactPriorityLevel {
switch (lanePriority) {
case SyncLanePriority:
return ImmediateSchedulerPriority;
case InputContinuousHydrationLanePriority:
case InputContinuousLanePriority:
return UserBlockingSchedulerPriority;
case DefaultHydrationLanePriority:
case DefaultLanePriority:
case TransitionHydrationPriority:
case TransitionPriority:
case SelectiveHydrationLanePriority:
case RetryLanePriority:
return NormalSchedulerPriority;
case IdleHydrationLanePriority:
case IdleLanePriority:
case OffscreenLanePriority:
return IdleSchedulerPriority;
case NoLanePriority:
return NoSchedulerPriority;
default:
invariant(
false,
'Invalid update priority: %s. This is a bug in React.',
lanePriority,
);
}
}

export function getNextLanes(root: FiberRoot, wipLanes: Lanes): Lanes {
// Early bailout if there's no pending work left.
const pendingLanes = root.pendingLanes;
Expand Down
42 changes: 1 addition & 41 deletions packages/react-reconciler/src/ReactFiberLane.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @flow
*/

import type {FiberRoot, ReactPriorityLevel} from './ReactInternalTypes';
import type {FiberRoot} from './ReactInternalTypes';

// TODO: Ideally these types would be opaque but that doesn't work well with
// our reconciler fork infra, since these leak into non-reconciler packages.
Expand Down Expand Up @@ -35,17 +35,8 @@ export type Lanes = number;
export type Lane = number;
export type LaneMap<T> = Array<T>;

import invariant from 'shared/invariant';
import {enableCache, enableSchedulingProfiler} from 'shared/ReactFeatureFlags';

import {
ImmediatePriority as ImmediateSchedulerPriority,
UserBlockingPriority as UserBlockingSchedulerPriority,
NormalPriority as NormalSchedulerPriority,
IdlePriority as IdleSchedulerPriority,
NoPriority as NoSchedulerPriority,
} from './SchedulerWithReactIntegration.old';

export const SyncLanePriority: LanePriority = 12;

const InputContinuousHydrationLanePriority: LanePriority = 11;
Expand Down Expand Up @@ -244,37 +235,6 @@ function getHighestPriorityLanes(lanes: Lanes | Lane): Lanes {
}
}

export function lanePriorityToSchedulerPriority(
lanePriority: LanePriority,
): ReactPriorityLevel {
switch (lanePriority) {
case SyncLanePriority:
return ImmediateSchedulerPriority;
case InputContinuousHydrationLanePriority:
case InputContinuousLanePriority:
return UserBlockingSchedulerPriority;
case DefaultHydrationLanePriority:
case DefaultLanePriority:
case TransitionHydrationPriority:
case TransitionPriority:
case SelectiveHydrationLanePriority:
case RetryLanePriority:
return NormalSchedulerPriority;
case IdleHydrationLanePriority:
case IdleLanePriority:
case OffscreenLanePriority:
return IdleSchedulerPriority;
case NoLanePriority:
return NoSchedulerPriority;
default:
invariant(
false,
'Invalid update priority: %s. This is a bug in React.',
lanePriority,
);
}
}

export function getNextLanes(root: FiberRoot, wipLanes: Lanes): Lanes {
// Early bailout if there's no pending work left.
const pendingLanes = root.pendingLanes;
Expand Down
4 changes: 2 additions & 2 deletions packages/react-reconciler/src/ReactFiberRoot.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import type {RootTag} from './ReactRootTags';
import {noTimeout, supportsHydration} from './ReactFiberHostConfig';
import {createHostRootFiber} from './ReactFiber.new';
import {
NoLane,
NoLanes,
NoLanePriority,
NoTimestamp,
createLaneMap,
} from './ReactFiberLane.new';
Expand All @@ -41,7 +41,7 @@ function FiberRootNode(containerInfo, tag, hydrate) {
this.pendingContext = null;
this.hydrate = hydrate;
this.callbackNode = null;
this.callbackPriority = NoLanePriority;
this.callbackPriority = NoLane;
this.eventTimes = createLaneMap(NoLanes);
this.expirationTimes = createLaneMap(NoTimestamp);

Expand Down
4 changes: 2 additions & 2 deletions packages/react-reconciler/src/ReactFiberRoot.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import type {RootTag} from './ReactRootTags';
import {noTimeout, supportsHydration} from './ReactFiberHostConfig';
import {createHostRootFiber} from './ReactFiber.old';
import {
NoLane,
NoLanes,
NoLanePriority,
NoTimestamp,
createLaneMap,
} from './ReactFiberLane.old';
Expand All @@ -41,7 +41,7 @@ function FiberRootNode(containerInfo, tag, hydrate) {
this.pendingContext = null;
this.hydrate = hydrate;
this.callbackNode = null;
this.callbackPriority = NoLanePriority;
this.callbackPriority = NoLane;
this.eventTimes = createLaneMap(NoLanes);
this.expirationTimes = createLaneMap(NoTimestamp);

Expand Down
43 changes: 30 additions & 13 deletions packages/react-reconciler/src/ReactFiberWorkLoop.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ import {
requestPaint,
now,
ImmediatePriority as ImmediateSchedulerPriority,
UserBlockingPriority as UserBlockingSchedulerPriority,
NormalPriority as NormalSchedulerPriority,
IdlePriority as IdleSchedulerPriority,
flushSyncCallbackQueue,
scheduleSyncCallback,
} from './SchedulerWithReactIntegration.new';
Expand Down Expand Up @@ -130,8 +132,6 @@ import {
MountLayoutDev,
} from './ReactFiberFlags';
import {
NoLanePriority,
SyncLanePriority,
NoLanes,
NoLane,
SyncLane,
Expand All @@ -147,7 +147,6 @@ import {
includesOnlyRetries,
includesOnlyTransitions,
getNextLanes,
returnNextLanesPriority,
markStarvedLanesAsExpired,
getLanesToRetrySynchronouslyOnError,
getMostRecentEventTime,
Expand All @@ -156,12 +155,14 @@ import {
markRootPinged,
markRootExpired,
markRootFinished,
lanePriorityToSchedulerPriority,
areLanesExpired,
getHighestPriorityLane,
} from './ReactFiberLane.new';
import {
DiscreteEventPriority,
ContinuousEventPriority,
DefaultEventPriority,
IdleEventPriority,
getCurrentUpdatePriority,
setCurrentUpdatePriority,
higherEventPriority,
Expand Down Expand Up @@ -653,19 +654,20 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
root,
root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes,
);
// This returns the priority level computed during the `getNextLanes` call.
const newCallbackPriority = returnNextLanesPriority();

if (nextLanes === NoLanes) {
// Special case: There's nothing to work on.
if (existingCallbackNode !== null) {
cancelCallback(existingCallbackNode);
}
root.callbackNode = null;
root.callbackPriority = NoLanePriority;
root.callbackPriority = NoLane;
return;
}

// We use the highest priority lane to represent the priority of the callback.
const newCallbackPriority = getHighestPriorityLane(nextLanes);

// Check if there's an existing task. We may be able to reuse it.
const existingCallbackPriority = root.callbackPriority;
if (existingCallbackPriority === newCallbackPriority) {
Expand All @@ -675,7 +677,7 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
// TODO: Temporary until we confirm this warning is not fired.
if (
existingCallbackNode == null &&
existingCallbackPriority !== SyncLanePriority
existingCallbackPriority !== SyncLane
) {
console.error(
'Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue.',
Expand All @@ -693,7 +695,7 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {

// Schedule a new callback.
let newCallbackNode;
if (newCallbackPriority === SyncLanePriority) {
if (newCallbackPriority === SyncLane) {
// Special case: Sync React callbacks are scheduled on a special
// internal queue
scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
Expand All @@ -706,9 +708,24 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
}
newCallbackNode = null;
} else {
const schedulerPriorityLevel = lanePriorityToSchedulerPriority(
newCallbackPriority,
);
let schedulerPriorityLevel;
switch (lanesToEventPriority(nextLanes)) {
case DiscreteEventPriority:
schedulerPriorityLevel = ImmediateSchedulerPriority;
break;
case ContinuousEventPriority:
schedulerPriorityLevel = UserBlockingSchedulerPriority;
break;
case DefaultEventPriority:
schedulerPriorityLevel = NormalSchedulerPriority;
break;
case IdleEventPriority:
schedulerPriorityLevel = IdleSchedulerPriority;
break;
default:
schedulerPriorityLevel = NormalSchedulerPriority;
break;
}
newCallbackNode = scheduleCallback(
schedulerPriorityLevel,
performConcurrentWorkOnRoot.bind(null, root),
Expand Down Expand Up @@ -1744,7 +1761,7 @@ function commitRootImpl(root, renderPriorityLevel) {
// commitRoot never returns a continuation; it always finishes synchronously.
// So we can clear these now to allow a new callback to be scheduled.
root.callbackNode = null;
root.callbackPriority = NoLanePriority;
root.callbackPriority = NoLane;

// Update the first and last pending times on this root. The new first
// pending time is whatever is left on the root fiber.
Expand Down
Loading

0 comments on commit dec2ae5

Please sign in to comment.