Skip to content

[Flight] Include env in ReactAsyncInfo and ReactIOInfo #33400

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions packages/react-client/src/ReactFlightClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -2758,9 +2758,7 @@ function resolveConsoleEntry(

function initializeIOInfo(response: Response, ioInfo: ReactIOInfo): void {
const env =
// TODO: Pass env through I/O info.
// ioInfo.env !== undefined ? ioInfo.env :
response._rootEnvironmentName;
ioInfo.env === undefined ? response._rootEnvironmentName : ioInfo.env;
if (ioInfo.stack !== undefined) {
initializeFakeTask(response, ioInfo, env);
initializeFakeStack(response, ioInfo);
Expand All @@ -2771,7 +2769,7 @@ function initializeIOInfo(response: Response, ioInfo: ReactIOInfo): void {
// $FlowFixMe[cannot-write]
ioInfo.end += response._timeOrigin;

logIOInfo(ioInfo);
logIOInfo(ioInfo, response._rootEnvironmentName);
}

function resolveIOInfo(
Expand Down
10 changes: 7 additions & 3 deletions packages/react-client/src/ReactFlightPerformanceTrack.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,19 +224,23 @@ function getIOColor(
}
}

export function logIOInfo(ioInfo: ReactIOInfo): void {
export function logIOInfo(ioInfo: ReactIOInfo, rootEnv: string): void {
const startTime = ioInfo.start;
const endTime = ioInfo.end;
if (supportsUserTiming && endTime >= 0) {
const name = ioInfo.name;
const env = ioInfo.env;
const isPrimaryEnv = env === rootEnv;
const entryName =
isPrimaryEnv || env === undefined ? name : name + ' [' + env + ']';
const debugTask = ioInfo.debugTask;
const color = getIOColor(name);
if (__DEV__ && debugTask) {
debugTask.run(
// $FlowFixMe[method-unbinding]
console.timeStamp.bind(
console,
name,
entryName,
startTime < 0 ? 0 : startTime,
endTime,
IO_TRACK,
Expand All @@ -246,7 +250,7 @@ export function logIOInfo(ioInfo: ReactIOInfo): void {
);
} else {
console.timeStamp(
name,
entryName,
startTime < 0 ? 0 : startTime,
endTime,
IO_TRACK,
Expand Down
30 changes: 29 additions & 1 deletion packages/react-server/src/ReactFlightServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1930,10 +1930,14 @@ function visitAsyncNode(
}
// Outline the IO node.
serializeIONode(request, ioNode);
// We log the environment at the time when the last promise pigned ping which may
// be later than what the environment was when we actually started awaiting.
const env = (0, request.environmentName)();
// Then emit a reference to us awaiting it in the current task.
request.pendingChunks++;
emitDebugChunk(request, task.id, {
awaited: ((ioNode: any): ReactIOInfo), // This is deduped by this reference.
env: env,
owner: node.owner,
stack: stack,
});
Expand Down Expand Up @@ -1969,8 +1973,12 @@ function emitAsyncSequence(
}
serializeIONode(request, awaitedNode);
request.pendingChunks++;
// We log the environment at the time when we ping which may be later than what the
// environment was when we actually started awaiting.
const env = (0, request.environmentName)();
emitDebugChunk(request, task.id, {
awaited: ((awaitedNode: any): ReactIOInfo), // This is deduped by this reference.
env: env,
});
}
}
Expand Down Expand Up @@ -3524,6 +3532,7 @@ function emitIOInfoChunk(
name: string,
start: number,
end: number,
env: ?string,
owner: ?ReactComponentInfo,
stack: ?ReactStackTrace,
): void {
Expand Down Expand Up @@ -3563,6 +3572,10 @@ function emitIOInfoChunk(
start: relativeStartTimestamp,
end: relativeEndTimestamp,
};
if (env != null) {
// $FlowFixMe[cannot-write]
debugIOInfo.env = env;
}
if (stack != null) {
// $FlowFixMe[cannot-write]
debugIOInfo.stack = stack;
Expand Down Expand Up @@ -3597,6 +3610,7 @@ function outlineIOInfo(request: Request, ioInfo: ReactIOInfo): void {
ioInfo.name,
ioInfo.start,
ioInfo.end,
ioInfo.env,
owner,
ioInfo.stack,
);
Expand Down Expand Up @@ -3633,9 +3647,22 @@ function serializeIONode(
outlineComponentInfo(request, owner);
}

// We log the environment at the time when we serialize the I/O node.
// The environment name may have changed from when the I/O was actually started.
const env = (0, request.environmentName)();

request.pendingChunks++;
const id = request.nextChunkId++;
emitIOInfoChunk(request, id, name, ioNode.start, ioNode.end, owner, stack);
emitIOInfoChunk(
request,
id,
name,
ioNode.start,
ioNode.end,
env,
owner,
stack,
);
const ref = serializeByValueID(id);
request.writtenObjects.set(ioNode, ref);
return ref;
Expand Down Expand Up @@ -4161,6 +4188,7 @@ function forwardDebugInfo(
const debugAsyncInfo: Omit<ReactAsyncInfo, 'debugTask' | 'debugStack'> =
{
awaited: ioInfo,
env: debugInfo[i].env,
owner: debugInfo[i].owner,
stack: debugInfo[i].stack,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ describe('ReactFlightAsyncDebugInfo', () => {
{
"awaited": {
"end": 0,
"env": "Server",
"name": "delay",
"owner": {
"env": "Server",
Expand Down Expand Up @@ -219,6 +220,7 @@ describe('ReactFlightAsyncDebugInfo', () => {
],
"start": 0,
},
"env": "Server",
"owner": {
"env": "Server",
"key": null,
Expand Down Expand Up @@ -258,6 +260,7 @@ describe('ReactFlightAsyncDebugInfo', () => {
{
"awaited": {
"end": 0,
"env": "Server",
"name": "delay",
"owner": {
"env": "Server",
Expand Down Expand Up @@ -304,6 +307,7 @@ describe('ReactFlightAsyncDebugInfo', () => {
],
"start": 0,
},
"env": "Server",
"owner": {
"env": "Server",
"key": null,
Expand Down Expand Up @@ -394,16 +398,17 @@ describe('ReactFlightAsyncDebugInfo', () => {
[
"Object.<anonymous>",
"/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
364,
368,
109,
351,
355,
67,
],
],
},
{
"awaited": {
"end": 0,
"env": "Server",
"name": "setTimeout",
"owner": {
"env": "Server",
Expand All @@ -415,9 +420,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
[
"Object.<anonymous>",
"/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
364,
368,
109,
351,
355,
67,
],
],
Expand All @@ -426,14 +431,15 @@ describe('ReactFlightAsyncDebugInfo', () => {
[
"Component",
"/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
354,
358,
7,
352,
356,
5,
],
],
"start": 0,
},
"env": "Server",
},
{
"time": 0,
Expand Down
2 changes: 2 additions & 0 deletions packages/shared/ReactTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ export type ReactIOInfo = {
+name: string, // the name of the async function being called (e.g. "fetch")
+start: number, // the start time
+end: number, // the end time (this might be different from the time the await was unblocked)
+env?: string, // the environment where this I/O was spawned.
+owner?: null | ReactComponentInfo,
+stack?: null | ReactStackTrace,
// Stashed Data for the Specific Execution Environment. Not part of the transport protocol
Expand All @@ -243,6 +244,7 @@ export type ReactIOInfo = {

export type ReactAsyncInfo = {
+awaited: ReactIOInfo,
+env?: string, // the environment where this was awaited. This might not be the same as where it was spawned.
+owner?: null | ReactComponentInfo,
+stack?: null | ReactStackTrace,
// Stashed Data for the Specific Execution Environment. Not part of the transport protocol
Expand Down
Loading