Skip to content

Commit

Permalink
[Flight] Transfer Debug Info in Server-to-Server Flight Requests (#28275
Browse files Browse the repository at this point in the history
)

A Flight Server can be a consumer of a stream from another Server. In
this case the meta data is attached to debugInfo properties on lazy,
Promises, Arrays or Elements that might in turn get forwarded to the
next stream. In this case we want to forward this debug information to
the client in the stream.

I also added a DEV only `environmentName` option to the Flight Server.
This lets you name the server that is producing the debug info so that
you can trace the origin of where that component is executing. This
defaults to `"server"`. DevTools could use this for badges or different
colors.

DiffTrain build for [629541b](629541b)
  • Loading branch information
sebmarkbage committed Feb 12, 2024
1 parent 9adade5 commit c4aeba9
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 11 deletions.
2 changes: 1 addition & 1 deletion compiled/facebook-www/REVISION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
35b2c28178bf4f79898d11dce0bc2a7ce675f670
629541bcc09fc7c0cc5c257541d084ee27457512
6 changes: 3 additions & 3 deletions compiled/facebook-www/ReactDOMTesting-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -17116,7 +17116,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1786 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-modern-6880028a",
version: "18.3.0-www-modern-9c7ddd0b",
rendererPackageName: "react-dom"
};
var internals$jscomp$inline_2162 = {
Expand Down Expand Up @@ -17147,7 +17147,7 @@ var internals$jscomp$inline_2162 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-modern-6880028a"
reconcilerVersion: "18.3.0-www-modern-9c7ddd0b"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_2163 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down Expand Up @@ -17575,4 +17575,4 @@ exports.useFormStatus = function () {
return ReactCurrentDispatcher$2.current.useHostTransitionStatus();
throw Error(formatProdErrorMessage(248));
};
exports.version = "18.3.0-www-modern-6880028a";
exports.version = "18.3.0-www-modern-9c7ddd0b";
101 changes: 95 additions & 6 deletions compiled/facebook-www/ReactFlightDOMServer-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -1104,7 +1104,8 @@ if (__DEV__) {
bundlerConfig,
onError,
identifierPrefix,
onPostpone
onPostpone,
environmentName
) {
if (
ReactCurrentCache.current !== null &&
Expand Down Expand Up @@ -1149,6 +1150,12 @@ if (__DEV__) {
onPostpone:
onPostpone === undefined ? defaultPostponeHandler : onPostpone
};

{
request.environmentName =
environmentName === undefined ? "server" : environmentName;
}

var rootTask = createTask(request, model, null, false, abortSet);
pingedTasks.push(rootTask);
return request;
Expand All @@ -1169,6 +1176,15 @@ if (__DEV__) {
request.abortableTasks
);

{
// If this came from Flight, forward any debug info into this new row.
var debugInfo = thenable._debugInfo;

if (debugInfo) {
forwardDebugInfo(request, newTask.id, debugInfo);
}
}

switch (thenable.status) {
case "fulfilled": {
// We have the resolved value, we can go ahead and schedule it for serialization.
Expand Down Expand Up @@ -1308,6 +1324,12 @@ if (__DEV__) {
_payload: thenable,
_init: readThenable
};

{
// If this came from React, transfer the debug info.
lazyType._debugInfo = thenable._debugInfo || [];
}

return lazyType;
}

Expand All @@ -1329,7 +1351,8 @@ if (__DEV__) {
var componentName = Component.displayName || Component.name || "";
request.pendingChunks++;
emitDebugChunk(request, debugID, {
name: componentName
name: componentName,
env: request.environmentName
});
}
}
Expand Down Expand Up @@ -1378,6 +1401,24 @@ if (__DEV__) {
}

function renderFragment(request, task, children) {
{
var debugInfo = children._debugInfo;

if (debugInfo) {
// If this came from Flight, forward any debug info into this new row.
if (debugID === null) {
// We don't have a chunk to assign debug info. We need to outline this
// component to assign it an ID.
return outlineTask(request, task);
} else {
// Forward any debug info we have the first time we see it.
// We do this after init so that we have received all the debug info
// from the server by the time we emit it.
forwardDebugInfo(request, debugID, debugInfo);
}
}
}

if (task.keyPath !== null) {
// We have a Server Component that specifies a key but we're now splitting
// the tree using a fragment.
Expand Down Expand Up @@ -1969,7 +2010,23 @@ if (__DEV__) {
_writtenObjects.set(value, -1);
}

var element = value; // Attempt to render the Server Component.
var element = value;

{
var debugInfo = value._debugInfo;

if (debugInfo) {
// If this came from Flight, forward any debug info into this new row.
if (debugID === null) {
// We don't have a chunk to assign debug info. We need to outline this
// component to assign it an ID.
return outlineTask(request, task);
} else {
// Forward any debug info we have the first time we see it.
forwardDebugInfo(request, debugID, debugInfo);
}
}
} // Attempt to render the Server Component.

return renderElement(
request,
Expand All @@ -1982,9 +2039,32 @@ if (__DEV__) {
}

case REACT_LAZY_TYPE: {
var payload = value._payload;
var init = value._init;
// Reset the task's thenable state before continuing. If there was one, it was
// from suspending the lazy before.
task.thenableState = null;
var lazy = value;
var payload = lazy._payload;
var init = lazy._init;
var resolvedModel = init(payload);

{
var _debugInfo = lazy._debugInfo;

if (_debugInfo) {
// If this came from Flight, forward any debug info into this new row.
if (debugID === null) {
// We don't have a chunk to assign debug info. We need to outline this
// component to assign it an ID.
return outlineTask(request, task);
} else {
// Forward any debug info we have the first time we see it.
// We do this after init so that we have received all the debug info
// from the server by the time we emit it.
forwardDebugInfo(request, debugID, _debugInfo);
}
}
}

return renderModelDestructive(
request,
task,
Expand Down Expand Up @@ -2310,6 +2390,13 @@ if (__DEV__) {
request.completedRegularChunks.push(processedChunk);
}

function forwardDebugInfo(request, id, debugInfo) {
for (var i = 0; i < debugInfo.length; i++) {
request.pendingChunks++;
emitDebugChunk(request, id, debugInfo[i]);
}
}

var emptyRoot = {};

function retryTask(request, task) {
Expand Down Expand Up @@ -2578,7 +2665,9 @@ if (__DEV__) {
var request = createRequest(
model,
null,
options ? options.onError : undefined
options ? options.onError : undefined,
undefined,
undefined
);
startWork(request);
startFlowing(request, destination);
Expand Down
1 change: 1 addition & 0 deletions compiled/facebook-www/ReactFlightDOMServer-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,7 @@ function renderModelDestructive(
);
case REACT_LAZY_TYPE:
return (
(task.thenableState = null),
(parent = value._init),
(value = parent(value._payload)),
renderModelDestructive(request, task, emptyRoot, "", value)
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/ReactTestRenderer-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -26096,7 +26096,7 @@ if (__DEV__) {
return root;
}

var ReactVersion = "18.3.0-www-modern-623a68d9";
var ReactVersion = "18.3.0-www-modern-f687cbe4";

// Might add PROFILE later.

Expand Down

0 comments on commit c4aeba9

Please sign in to comment.