[Flight] Emit start time before an await if one wasn't emitted already (#33646)

There's a special case where if we create a new task, e.g. to serialize
a promise like `<div>{promise}</div>` then that row doesn't have any
start time emitted but it has a `task.time` inherited. We mostly don't
need this because every other operation emits its own start time. E.g.
when we started rendering a Server Component or the real start time of a
real `await`.

For these implied awaits we don't have a start time. Ideally it would
probably be when we started the serialization, like when we called
`.then()` but we can't just emit that eagerly and we can't just advance
the `task.time` because that time represents the last render or previous
await and we use that to cut off awaits. However for this case we don't
want to cut off any inner awaits inside the node we're serializing if
they happened before the `.then()`.

Therefore, I just use the time of the previous operation - which is
likely either the resolution of a previous promise that blocked the
`<div>` like the promise of the Server Component that rendered it, or
just the start of the Server Component if it was sync.
This commit is contained in:
Sebastian Markbåge 2025-06-25 17:28:59 -04:00 committed by GitHub
parent 9b2a545b32
commit 9406162bc9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -2211,6 +2211,10 @@ function emitAsyncSequence(
debugInfo.stack = filterStackTrace(request, parseStackTrace(stack, 1));
}
}
// We don't have a start time for this await but in case there was no start time emitted
// we need to include something. TODO: We should maybe ideally track the time when we
// called .then() but without updating the task.time field since that's used for the cutoff.
advanceTaskTime(request, task, task.time);
emitDebugChunk(request, task.id, debugInfo);
// Mark the end time of the await. If we're aborting then we don't emit this
// to signal that this never resolved inside this render.
@ -4752,6 +4756,10 @@ function forwardDebugInfoFromAbortedTask(request: Request, task: Task): void {
awaited: ((node: any): ReactIOInfo), // This is deduped by this reference.
env: env,
};
// We don't have a start time for this await but in case there was no start time emitted
// we need to include something. TODO: We should maybe ideally track the time when we
// called .then() but without updating the task.time field since that's used for the cutoff.
advanceTaskTime(request, task, task.time);
emitDebugChunk(request, task.id, asyncInfo);
} else {
emitAsyncSequence(request, task, sequence, debugInfo, null, null);