Skip to content

Commit bfc8801

Browse files
authored
[Flight] Write Debug Info to Separate Priority Queue (#33654)
This writes all debug info to a separate priority queue. In the future I'll put this on a different channel. Ideally I think we'd put it in the bottom of the stream but because it actually blocks the elements from resolving anyway it ends up being better to put them ahead. At least for now. When we have two separate channels it's not possible to rely on the order for consistency Even then we might write to that queue first for this reason. We can't rely on it though. Which will show up like things turning into Lazy instead of Element similar to how outlining can.
1 parent d2a288f commit bfc8801

File tree

3 files changed

+354
-135
lines changed

3 files changed

+354
-135
lines changed

packages/react-client/src/ReactFlightClient.js

Lines changed: 87 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,78 @@ function getTaskName(type: mixed): string {
764764
}
765765
}
766766

767+
function initializeElement(response: Response, element: any): void {
768+
if (!__DEV__) {
769+
return;
770+
}
771+
const stack = element._debugStack;
772+
const owner = element._owner;
773+
if (owner === null) {
774+
element._owner = response._debugRootOwner;
775+
}
776+
let env = response._rootEnvironmentName;
777+
if (owner !== null && owner.env != null) {
778+
// Interestingly we don't actually have the environment name of where
779+
// this JSX was created if it doesn't have an owner but if it does
780+
// it must be the same environment as the owner. We could send it separately
781+
// but it seems a bit unnecessary for this edge case.
782+
env = owner.env;
783+
}
784+
let normalizedStackTrace: null | Error = null;
785+
if (owner === null && response._debugRootStack != null) {
786+
// We override the stack if we override the owner since the stack where the root JSX
787+
// was created on the server isn't very useful but where the request was made is.
788+
normalizedStackTrace = response._debugRootStack;
789+
} else if (stack !== null) {
790+
// We create a fake stack and then create an Error object inside of it.
791+
// This means that the stack trace is now normalized into the native format
792+
// of the browser and the stack frames will have been registered with
793+
// source mapping information.
794+
// This can unfortunately happen within a user space callstack which will
795+
// remain on the stack.
796+
normalizedStackTrace = createFakeJSXCallStackInDEV(response, stack, env);
797+
}
798+
element._debugStack = normalizedStackTrace;
799+
let task: null | ConsoleTask = null;
800+
if (supportsCreateTask && stack !== null) {
801+
const createTaskFn = (console: any).createTask.bind(
802+
console,
803+
getTaskName(element.type),
804+
);
805+
const callStack = buildFakeCallStack(
806+
response,
807+
stack,
808+
env,
809+
false,
810+
createTaskFn,
811+
);
812+
// This owner should ideally have already been initialized to avoid getting
813+
// user stack frames on the stack.
814+
const ownerTask =
815+
owner === null ? null : initializeFakeTask(response, owner);
816+
if (ownerTask === null) {
817+
const rootTask = response._debugRootTask;
818+
if (rootTask != null) {
819+
task = rootTask.run(callStack);
820+
} else {
821+
task = callStack();
822+
}
823+
} else {
824+
task = ownerTask.run(callStack);
825+
}
826+
}
827+
element._debugTask = task;
828+
829+
// This owner should ideally have already been initialized to avoid getting
830+
// user stack frames on the stack.
831+
if (owner !== null) {
832+
initializeFakeStack(response, owner);
833+
}
834+
// TODO: We should be freezing the element but currently, we might write into
835+
// _debugInfo later. We could move it into _store which remains mutable.
836+
Object.freeze(element.props);
837+
}
838+
767839
function createElement(
768840
response: Response,
769841
type: mixed,
@@ -783,7 +855,7 @@ function createElement(
783855
type,
784856
key,
785857
props,
786-
_owner: __DEV__ && owner === null ? response._debugRootOwner : owner,
858+
_owner: owner,
787859
}: any);
788860
Object.defineProperty(element, 'ref', {
789861
enumerable: false,
@@ -821,75 +893,18 @@ function createElement(
821893
writable: true,
822894
value: null,
823895
});
824-
let env = response._rootEnvironmentName;
825-
if (owner !== null && owner.env != null) {
826-
// Interestingly we don't actually have the environment name of where
827-
// this JSX was created if it doesn't have an owner but if it does
828-
// it must be the same environment as the owner. We could send it separately
829-
// but it seems a bit unnecessary for this edge case.
830-
env = owner.env;
831-
}
832-
let normalizedStackTrace: null | Error = null;
833-
if (owner === null && response._debugRootStack != null) {
834-
// We override the stack if we override the owner since the stack where the root JSX
835-
// was created on the server isn't very useful but where the request was made is.
836-
normalizedStackTrace = response._debugRootStack;
837-
} else if (stack !== null) {
838-
// We create a fake stack and then create an Error object inside of it.
839-
// This means that the stack trace is now normalized into the native format
840-
// of the browser and the stack frames will have been registered with
841-
// source mapping information.
842-
// This can unfortunately happen within a user space callstack which will
843-
// remain on the stack.
844-
normalizedStackTrace = createFakeJSXCallStackInDEV(response, stack, env);
845-
}
846896
Object.defineProperty(element, '_debugStack', {
847897
configurable: false,
848898
enumerable: false,
849899
writable: true,
850-
value: normalizedStackTrace,
900+
value: stack,
851901
});
852-
853-
let task: null | ConsoleTask = null;
854-
if (supportsCreateTask && stack !== null) {
855-
const createTaskFn = (console: any).createTask.bind(
856-
console,
857-
getTaskName(type),
858-
);
859-
const callStack = buildFakeCallStack(
860-
response,
861-
stack,
862-
env,
863-
false,
864-
createTaskFn,
865-
);
866-
// This owner should ideally have already been initialized to avoid getting
867-
// user stack frames on the stack.
868-
const ownerTask =
869-
owner === null ? null : initializeFakeTask(response, owner);
870-
if (ownerTask === null) {
871-
const rootTask = response._debugRootTask;
872-
if (rootTask != null) {
873-
task = rootTask.run(callStack);
874-
} else {
875-
task = callStack();
876-
}
877-
} else {
878-
task = ownerTask.run(callStack);
879-
}
880-
}
881902
Object.defineProperty(element, '_debugTask', {
882903
configurable: false,
883904
enumerable: false,
884905
writable: true,
885-
value: task,
906+
value: null,
886907
});
887-
888-
// This owner should ideally have already been initialized to avoid getting
889-
// user stack frames on the stack.
890-
if (owner !== null) {
891-
initializeFakeStack(response, owner);
892-
}
893908
}
894909

895910
if (initializingHandler !== null) {
@@ -905,6 +920,7 @@ function createElement(
905920
handler.value,
906921
);
907922
if (__DEV__) {
923+
initializeElement(response, element);
908924
// Conceptually the error happened inside this Element but right before
909925
// it was rendered. We don't have a client side component to render but
910926
// we can add some DebugInfo to explain that this was conceptually a
@@ -933,15 +949,15 @@ function createElement(
933949
handler.value = element;
934950
handler.chunk = blockedChunk;
935951
if (__DEV__) {
936-
const freeze = Object.freeze.bind(Object, element.props);
937-
blockedChunk.then(freeze, freeze);
952+
/// After we have initialized any blocked references, initialize stack etc.
953+
const init = initializeElement.bind(null, response, element);
954+
blockedChunk.then(init, init);
938955
}
939956
return createLazyChunkWrapper(blockedChunk);
940957
}
941-
} else if (__DEV__) {
942-
// TODO: We should be freezing the element but currently, we might write into
943-
// _debugInfo later. We could move it into _store which remains mutable.
944-
Object.freeze(element.props);
958+
}
959+
if (__DEV__) {
960+
initializeElement(response, element);
945961
}
946962

947963
return element;
@@ -1055,6 +1071,11 @@ function waitForReference<T>(
10551071
element._owner = mappedValue;
10561072
}
10571073
break;
1074+
case '5':
1075+
if (__DEV__) {
1076+
element._debugStack = mappedValue;
1077+
}
1078+
break;
10581079
}
10591080
}
10601081

packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ describe('ReactFlightDOMEdge', () => {
674674
const [stream2, drip] = dripStream(stream);
675675

676676
// Allow some of the content through.
677-
drip(5000);
677+
drip(__DEV__ ? 7500 : 5000);
678678

679679
const result = await ReactServerDOMClient.createFromReadableStream(
680680
stream2,

0 commit comments

Comments
 (0)