Skip to content

Commit

Permalink
Work-in-progress
Browse files Browse the repository at this point in the history
  • Loading branch information
acdlite committed Mar 21, 2019
1 parent b1a56ab commit fc0d30e
Show file tree
Hide file tree
Showing 23 changed files with 2,676 additions and 558 deletions.
7 changes: 5 additions & 2 deletions packages/react-cache/src/LRU.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import * as Scheduler from 'scheduler';

// Intentionally not named imports because Rollup would
// use dynamic dispatch for CommonJS interop named imports.
const {unstable_scheduleCallback: scheduleCallback} = Scheduler;
const {
unstable_scheduleCallback: scheduleCallback,
unstable_IdlePriority: IdlePriority,
} = Scheduler;

type Entry<T> = {|
value: T,
Expand All @@ -34,7 +37,7 @@ export function createLRU<T>(limit: number) {
// The cache size exceeds the limit. Schedule a callback to delete the
// least recently used entries.
cleanUpIsScheduled = true;
scheduleCallback(cleanUp);
scheduleCallback(IdlePriority, cleanUp);
}
}

Expand Down
3 changes: 2 additions & 1 deletion packages/react-dom/src/__tests__/ReactDOMHooks-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ describe('ReactDOMHooks', () => {
expect(container3.textContent).toBe('6');
});

it('can batch synchronous work inside effects with other work', () => {
// TODO: This behavior is wrong. Fix this in the old implementation.
it.skip('can batch synchronous work inside effects with other work', () => {
let otherContainer = document.createElement('div');

let calledA = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ let ReactDOM;
let Suspense;
let ReactCache;
let ReactTestUtils;
let Scheduler;
let TextResource;
let act;

Expand All @@ -26,6 +27,7 @@ describe('ReactDOMSuspensePlaceholder', () => {
ReactDOM = require('react-dom');
ReactCache = require('react-cache');
ReactTestUtils = require('react-dom/test-utils');
Scheduler = require('scheduler');
act = ReactTestUtils.act;
Suspense = React.Suspense;
container = document.createElement('div');
Expand Down Expand Up @@ -94,6 +96,8 @@ describe('ReactDOMSuspensePlaceholder', () => {

await advanceTimers(1000);

Scheduler.flushAll();

expect(divs[0].current.style.display).toEqual('');
expect(divs[1].current.style.display).toEqual('');
// This div's display was set with a prop.
Expand All @@ -115,6 +119,8 @@ describe('ReactDOMSuspensePlaceholder', () => {

await advanceTimers(1000);

Scheduler.flushAll();

expect(container.textContent).toEqual('ABC');
});

Expand Down Expand Up @@ -160,6 +166,8 @@ describe('ReactDOMSuspensePlaceholder', () => {

await advanceTimers(1000);

Scheduler.flushAll();

expect(container.innerHTML).toEqual(
'<span style="display: inline;">Sibling</span><span style="">Async</span>',
);
Expand Down
2 changes: 1 addition & 1 deletion packages/react-reconciler/src/ReactDebugFiberPerf.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ export function stopRequestCallbackTimer(
expirationTime: number,
): void {
if (enableUserTimingAPI) {
if (supportsUserTiming) {
if (supportsUserTiming && isWaitingForCallback) {
isWaitingForCallback = false;
const warning = didExpire ? 'React was blocked by main thread' : null;
endMark(
Expand Down
39 changes: 39 additions & 0 deletions packages/react-reconciler/src/ReactFiberExpirationTime.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,17 @@
* @flow
*/

import type {ReactPriorityLevel} from './SchedulerWithReactIntegration';

import MAX_SIGNED_31_BIT_INT from './maxSigned31BitInt';

import {
ImmediatePriority,
UserBlockingPriority,
NormalPriority,
IdlePriority,
} from './SchedulerWithReactIntegration';

export type ExpirationTime = number;

export const NoWork = 0;
Expand Down Expand Up @@ -46,6 +55,8 @@ function computeExpirationBucket(
);
}

// TODO: This corresponds to Scheduler's NormalPriority, not LowPriority. Update
// the names to reflect.
export const LOW_PRIORITY_EXPIRATION = 5000;
export const LOW_PRIORITY_BATCH_SIZE = 250;

Expand Down Expand Up @@ -80,3 +91,31 @@ export function computeInteractiveExpiration(currentTime: ExpirationTime) {
HIGH_PRIORITY_BATCH_SIZE,
);
}

export function inferPriorityFromExpirationTime(
currentTime: ExpirationTime,
expirationTime: ExpirationTime,
): ReactPriorityLevel {
if (expirationTime === Sync) {
return ImmediatePriority;
}
if (expirationTime === Never) {
return IdlePriority;
}
const msUntil =
msToExpirationTime(expirationTime) - msToExpirationTime(currentTime);
if (msUntil <= 0) {
return ImmediatePriority;
}
if (msUntil <= HIGH_PRIORITY_EXPIRATION) {
return UserBlockingPriority;
}
if (msUntil <= LOW_PRIORITY_EXPIRATION) {
return NormalPriority;
}

// TODO: Handle LowPriority

// Assume anything lower has idle priority
return IdlePriority;
}
2 changes: 0 additions & 2 deletions packages/react-reconciler/src/ReactFiberReconciler.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ import {
requestCurrentTime,
computeExpirationForFiber,
scheduleWork,
requestWork,
flushRoot,
batchedUpdates,
unbatchedUpdates,
Expand Down Expand Up @@ -300,7 +299,6 @@ export function updateContainer(

export {
flushRoot,
requestWork,
computeUniqueAsyncExpiration,
batchedUpdates,
unbatchedUpdates,
Expand Down
19 changes: 19 additions & 0 deletions packages/react-reconciler/src/ReactFiberRoot.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ type BaseFiberRootProperties = {|
firstBatch: Batch | null,
// Linked-list of roots
nextScheduledRoot: FiberRoot | null,

// New Scheduler fields
callbackNode: *,
callbackExpirationTime: ExpirationTime,
firstPendingTime: ExpirationTime,
lastPendingTime: ExpirationTime,
pingTime: ExpirationTime,
|};

// The following attributes are only used by interaction tracing builds.
Expand Down Expand Up @@ -145,6 +152,12 @@ export function createFiberRoot(
interactionThreadID: unstable_getThreadID(),
memoizedInteractions: new Set(),
pendingInteractionMap: new Map(),

callbackNode: null,
callbackExpirationTime: NoWork,
firstPendingTime: NoWork,
lastPendingTime: NoWork,
pingTime: NoWork,
}: FiberRoot);
} else {
root = ({
Expand Down Expand Up @@ -172,6 +185,12 @@ export function createFiberRoot(
expirationTime: NoWork,
firstBatch: null,
nextScheduledRoot: null,

callbackNode: null,
callbackExpirationTime: NoWork,
firstPendingTime: NoWork,
lastPendingTime: NoWork,
pingTime: NoWork,
}: BaseFiberRootProperties);
}

Expand Down
8 changes: 4 additions & 4 deletions packages/react-reconciler/src/ReactFiberScheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import {
markLegacyErrorBoundaryAsFailed as markLegacyErrorBoundaryAsFailed_old,
isAlreadyFailedLegacyErrorBoundary as isAlreadyFailedLegacyErrorBoundary_old,
scheduleWork as scheduleWork_old,
requestWork as requestWork_old,
flushRoot as flushRoot_old,
batchedUpdates as batchedUpdates_old,
unbatchedUpdates as unbatchedUpdates_old,
Expand All @@ -35,6 +34,7 @@ import {
computeUniqueAsyncExpiration as computeUniqueAsyncExpiration_old,
flushPassiveEffects as flushPassiveEffects_old,
warnIfNotCurrentlyBatchingInDev as warnIfNotCurrentlyBatchingInDev_old,
inferStartTimeFromExpirationTime as inferStartTimeFromExpirationTime_old,
} from './ReactFiberScheduler.old';

import {
Expand All @@ -50,7 +50,6 @@ import {
markLegacyErrorBoundaryAsFailed as markLegacyErrorBoundaryAsFailed_new,
isAlreadyFailedLegacyErrorBoundary as isAlreadyFailedLegacyErrorBoundary_new,
scheduleWork as scheduleWork_new,
requestWork as requestWork_new,
flushRoot as flushRoot_new,
batchedUpdates as batchedUpdates_new,
unbatchedUpdates as unbatchedUpdates_new,
Expand All @@ -63,6 +62,7 @@ import {
computeUniqueAsyncExpiration as computeUniqueAsyncExpiration_new,
flushPassiveEffects as flushPassiveEffects_new,
warnIfNotCurrentlyBatchingInDev as warnIfNotCurrentlyBatchingInDev_new,
inferStartTimeFromExpirationTime as inferStartTimeFromExpirationTime_new,
} from './ReactFiberScheduler.new';

export let requestCurrentTime = requestCurrentTime_old;
Expand All @@ -77,7 +77,6 @@ export let resolveRetryThenable = resolveRetryThenable_old;
export let markLegacyErrorBoundaryAsFailed = markLegacyErrorBoundaryAsFailed_old;
export let isAlreadyFailedLegacyErrorBoundary = isAlreadyFailedLegacyErrorBoundary_old;
export let scheduleWork = scheduleWork_old;
export let requestWork = requestWork_old;
export let flushRoot = flushRoot_old;
export let batchedUpdates = batchedUpdates_old;
export let unbatchedUpdates = unbatchedUpdates_old;
Expand All @@ -90,6 +89,7 @@ export let flushInteractiveUpdates = flushInteractiveUpdates_old;
export let computeUniqueAsyncExpiration = computeUniqueAsyncExpiration_old;
export let flushPassiveEffects = flushPassiveEffects_old;
export let warnIfNotCurrentlyBatchingInDev = warnIfNotCurrentlyBatchingInDev_old;
export let inferStartTimeFromExpirationTime = inferStartTimeFromExpirationTime_old;

if (enableNewScheduler) {
requestCurrentTime = requestCurrentTime_new;
Expand All @@ -104,7 +104,6 @@ if (enableNewScheduler) {
markLegacyErrorBoundaryAsFailed = markLegacyErrorBoundaryAsFailed_new;
isAlreadyFailedLegacyErrorBoundary = isAlreadyFailedLegacyErrorBoundary_new;
scheduleWork = scheduleWork_new;
requestWork = requestWork_new;
flushRoot = flushRoot_new;
batchedUpdates = batchedUpdates_new;
unbatchedUpdates = unbatchedUpdates_new;
Expand All @@ -117,6 +116,7 @@ if (enableNewScheduler) {
computeUniqueAsyncExpiration = computeUniqueAsyncExpiration_new;
flushPassiveEffects = flushPassiveEffects_new;
warnIfNotCurrentlyBatchingInDev = warnIfNotCurrentlyBatchingInDev_new;
inferStartTimeFromExpirationTime = inferStartTimeFromExpirationTime_new;
}

export type Thenable = {
Expand Down
Loading

0 comments on commit fc0d30e

Please sign in to comment.