Skip to content

Commit

Permalink
Use callback priority to determine cancellation
Browse files Browse the repository at this point in the history
  • Loading branch information
rickhanlonii committed Jan 27, 2021
1 parent bf6990a commit bd9672d
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 19 deletions.
27 changes: 18 additions & 9 deletions packages/react-reconciler/src/ReactFiberWorkLoop.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -716,21 +716,27 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
// Special case: There's nothing to work on.
if (existingCallbackNode !== null) {
cancelCallback(existingCallbackNode);
root.callbackNode = null;
root.callbackPriority = NoLanePriority;
}
root.callbackNode = null;
root.callbackPriority = NoLanePriority;
return;
}

// Check if there's an existing task. We may be able to reuse it.
if (existingCallbackNode !== null) {
const existingCallbackPriority = root.callbackPriority;
if (existingCallbackPriority === newCallbackPriority) {
// The priority hasn't changed. We can reuse the existing task. Exit.
return;
const existingCallbackPriority = root.callbackPriority;
if (existingCallbackPriority === newCallbackPriority) {
if (__DEV__) {
invariant(
existingCallbackNode,
'Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue.',
);
}
// The priority changed. Cancel the existing callback. We'll schedule a new
// one below.
// The priority hasn't changed. We can reuse the existing task. Exit.
return;
}

if (existingCallbackNode != null) {
// Cancel the existing callback. We'll schedule a new one below.
cancelCallback(existingCallbackNode);
}

Expand All @@ -739,6 +745,8 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
if (newCallbackPriority === SyncLanePriority) {
// Special case: Sync React callbacks are scheduled on a special
// internal queue

// TODO: After enableDiscreteEventMicroTasks lands, we can remove the fake node.
newCallbackNode = scheduleSyncCallback(
performSyncWorkOnRoot.bind(null, root),
);
Expand Down Expand Up @@ -1879,6 +1887,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;

// 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
27 changes: 18 additions & 9 deletions packages/react-reconciler/src/ReactFiberWorkLoop.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -698,21 +698,27 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
// Special case: There's nothing to work on.
if (existingCallbackNode !== null) {
cancelCallback(existingCallbackNode);
root.callbackNode = null;
root.callbackPriority = NoLanePriority;
}
root.callbackNode = null;
root.callbackPriority = NoLanePriority;
return;
}

// Check if there's an existing task. We may be able to reuse it.
if (existingCallbackNode !== null) {
const existingCallbackPriority = root.callbackPriority;
if (existingCallbackPriority === newCallbackPriority) {
// The priority hasn't changed. We can reuse the existing task. Exit.
return;
const existingCallbackPriority = root.callbackPriority;
if (existingCallbackPriority === newCallbackPriority) {
if (__DEV__) {
invariant(
existingCallbackNode,
'Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue.',
);
}
// The priority changed. Cancel the existing callback. We'll schedule a new
// one below.
// The priority hasn't changed. We can reuse the existing task. Exit.
return;
}

if (existingCallbackNode != null) {
// Cancel the existing callback. We'll schedule a new one below.
cancelCallback(existingCallbackNode);
}

Expand All @@ -721,6 +727,8 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
if (newCallbackPriority === SyncLanePriority) {
// Special case: Sync React callbacks are scheduled on a special
// internal queue

// TODO: After enableDiscreteEventMicroTasks lands, we can remove the fake node.
newCallbackNode = scheduleSyncCallback(
performSyncWorkOnRoot.bind(null, root),
);
Expand Down Expand Up @@ -1859,6 +1867,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;

// 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
3 changes: 2 additions & 1 deletion scripts/error-codes/codes.json
Original file line number Diff line number Diff line change
Expand Up @@ -372,5 +372,6 @@
"381": "This feature is not supported by ReactSuspenseTestUtils.",
"382": "This query has received more parameters than the last time the same query was used. Always pass the exact number of parameters that the query needs.",
"383": "This query has received fewer parameters than the last time the same query was used. Always pass the exact number of parameters that the query needs.",
"384": "Refreshing the cache is not supported in Server Components."
"384": "Refreshing the cache is not supported in Server Components.",
"385": "Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue."
}

0 comments on commit bd9672d

Please sign in to comment.