Skip to content

Commit 24721ff

Browse files
committed
[Fizz][Float] Do not write after closing the stream (#27541)
Float methods can hang on to a reference to a Request after the request is closed due to AsyncLocalStorage. If a Float method is called at this point we do not want to attempt to flush anything. This change updates the closing logic to also call `stopFlowing` which will ensure that any checks against the destination properly reflect that we cannot do any writes. In addition it updates the enqueueFlush logic to existence check the destination inside the work function since it can change across the work scheduling gap if it is async. fixes: #27540 DiffTrain build for [601e5c3](601e5c3)
1 parent 1050447 commit 24721ff

9 files changed

+106
-67
lines changed

compiled/facebook-www/REVISION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
75c1bd7ee7e4a87a4dd0f560e157c57957ef823b
1+
601e5c38505ebc0ee099d8666b2f7a8b03159ac4

compiled/facebook-www/ReactART-dev.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ function _assertThisInitialized(self) {
6969
return self;
7070
}
7171

72-
var ReactVersion = "18.3.0-www-modern-f972e958";
72+
var ReactVersion = "18.3.0-www-modern-6d0bc8c7";
7373

7474
var LegacyRoot = 0;
7575
var ConcurrentRoot = 1;

compiled/facebook-www/ReactART-prod.modern.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9848,7 +9848,7 @@ var slice = Array.prototype.slice,
98489848
return null;
98499849
},
98509850
bundleType: 0,
9851-
version: "18.3.0-www-modern-4a0e1ba5",
9851+
version: "18.3.0-www-modern-75350665",
98529852
rendererPackageName: "react-art"
98539853
};
98549854
var internals$jscomp$inline_1302 = {
@@ -9879,7 +9879,7 @@ var internals$jscomp$inline_1302 = {
98799879
scheduleRoot: null,
98809880
setRefreshHandler: null,
98819881
getCurrentFiber: null,
9882-
reconcilerVersion: "18.3.0-www-modern-4a0e1ba5"
9882+
reconcilerVersion: "18.3.0-www-modern-75350665"
98839883
};
98849884
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
98859885
var hook$jscomp$inline_1303 = __REACT_DEVTOOLS_GLOBAL_HOOK__;

compiled/facebook-www/ReactDOMServer-dev.classic.js

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ if (__DEV__) {
1919
var React = require("react");
2020
var ReactDOM = require("react-dom");
2121

22-
var ReactVersion = "18.3.0-www-classic-c2fb22b9";
22+
var ReactVersion = "18.3.0-www-classic-89c1183f";
2323

2424
// This refers to a WWW module.
2525
var warningWWW = require("warning");
@@ -13209,7 +13209,10 @@ function flushCompletedQueues(request, destination) {
1320913209
}
1321013210
} // We're done.
1321113211

13212-
close(destination);
13212+
close(destination); // We need to stop flowing now because we do not want any async contexts which might call
13213+
// float methods to initiate any flushes after this point
13214+
13215+
stopFlowing(request);
1321313216
}
1321413217
}
1321513218
}
@@ -13231,10 +13234,17 @@ function enqueueFlush(request) {
1323113234
// happen when we start flowing again
1323213235
request.destination !== null
1323313236
) {
13234-
var destination = request.destination;
1323513237
request.flushScheduled = true;
1323613238
scheduleWork(function () {
13237-
return flushCompletedQueues(request, destination);
13239+
// We need to existence check destination again here because it might go away
13240+
// in between the enqueueFlush call and the work execution
13241+
var destination = request.destination;
13242+
13243+
if (destination) {
13244+
flushCompletedQueues(request, destination);
13245+
} else {
13246+
request.flushScheduled = false;
13247+
}
1323813248
});
1323913249
}
1324013250
}
@@ -13264,6 +13274,9 @@ function startFlowing(request, destination) {
1326413274
fatalError(request, error);
1326513275
}
1326613276
}
13277+
function stopFlowing(request) {
13278+
request.destination = null;
13279+
} // This is called to early terminate a request. It puts all pending boundaries in client rendered state.
1326713280

1326813281
function abort(request, reason) {
1326913282
try {

compiled/facebook-www/ReactDOMServer-dev.modern.js

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ if (__DEV__) {
1919
var React = require("react");
2020
var ReactDOM = require("react-dom");
2121

22-
var ReactVersion = "18.3.0-www-modern-f972e958";
22+
var ReactVersion = "18.3.0-www-modern-6d0bc8c7";
2323

2424
// This refers to a WWW module.
2525
var warningWWW = require("warning");
@@ -12957,7 +12957,10 @@ function flushCompletedQueues(request, destination) {
1295712957
}
1295812958
} // We're done.
1295912959

12960-
close(destination);
12960+
close(destination); // We need to stop flowing now because we do not want any async contexts which might call
12961+
// float methods to initiate any flushes after this point
12962+
12963+
stopFlowing(request);
1296112964
}
1296212965
}
1296312966
}
@@ -12979,10 +12982,17 @@ function enqueueFlush(request) {
1297912982
// happen when we start flowing again
1298012983
request.destination !== null
1298112984
) {
12982-
var destination = request.destination;
1298312985
request.flushScheduled = true;
1298412986
scheduleWork(function () {
12985-
return flushCompletedQueues(request, destination);
12987+
// We need to existence check destination again here because it might go away
12988+
// in between the enqueueFlush call and the work execution
12989+
var destination = request.destination;
12990+
12991+
if (destination) {
12992+
flushCompletedQueues(request, destination);
12993+
} else {
12994+
request.flushScheduled = false;
12995+
}
1298612996
});
1298712997
}
1298812998
}
@@ -13012,6 +13022,9 @@ function startFlowing(request, destination) {
1301213022
fatalError(request, error);
1301313023
}
1301413024
}
13025+
function stopFlowing(request) {
13026+
request.destination = null;
13027+
} // This is called to early terminate a request. It puts all pending boundaries in client rendered state.
1301513028

1301613029
function abort(request, reason) {
1301713030
try {

compiled/facebook-www/ReactDOMServer-prod.classic.js

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2287,24 +2287,24 @@ function hoistStylesheetDependency(stylesheet) {
22872287
function createRenderState(resumableState, generateStaticMarkup) {
22882288
var idPrefix = resumableState.idPrefix;
22892289
resumableState = idPrefix + "P:";
2290-
var JSCompiler_object_inline_segmentPrefix_1570 = idPrefix + "S:";
2290+
var JSCompiler_object_inline_segmentPrefix_1574 = idPrefix + "S:";
22912291
idPrefix += "B:";
2292-
var JSCompiler_object_inline_preconnects_1582 = new Set(),
2293-
JSCompiler_object_inline_fontPreloads_1583 = new Set(),
2294-
JSCompiler_object_inline_highImagePreloads_1584 = new Set(),
2295-
JSCompiler_object_inline_styles_1585 = new Map(),
2296-
JSCompiler_object_inline_bootstrapScripts_1586 = new Set(),
2297-
JSCompiler_object_inline_scripts_1587 = new Set(),
2298-
JSCompiler_object_inline_bulkPreloads_1588 = new Set(),
2299-
JSCompiler_object_inline_preloads_1589 = {
2292+
var JSCompiler_object_inline_preconnects_1586 = new Set(),
2293+
JSCompiler_object_inline_fontPreloads_1587 = new Set(),
2294+
JSCompiler_object_inline_highImagePreloads_1588 = new Set(),
2295+
JSCompiler_object_inline_styles_1589 = new Map(),
2296+
JSCompiler_object_inline_bootstrapScripts_1590 = new Set(),
2297+
JSCompiler_object_inline_scripts_1591 = new Set(),
2298+
JSCompiler_object_inline_bulkPreloads_1592 = new Set(),
2299+
JSCompiler_object_inline_preloads_1593 = {
23002300
images: new Map(),
23012301
stylesheets: new Map(),
23022302
scripts: new Map(),
23032303
moduleScripts: new Map()
23042304
};
23052305
return {
23062306
placeholderPrefix: resumableState,
2307-
segmentPrefix: JSCompiler_object_inline_segmentPrefix_1570,
2307+
segmentPrefix: JSCompiler_object_inline_segmentPrefix_1574,
23082308
boundaryPrefix: idPrefix,
23092309
startInlineScript: "<script>",
23102310
htmlChunks: null,
@@ -2316,14 +2316,14 @@ function createRenderState(resumableState, generateStaticMarkup) {
23162316
importMapChunks: [],
23172317
preloadChunks: [],
23182318
hoistableChunks: [],
2319-
preconnects: JSCompiler_object_inline_preconnects_1582,
2320-
fontPreloads: JSCompiler_object_inline_fontPreloads_1583,
2321-
highImagePreloads: JSCompiler_object_inline_highImagePreloads_1584,
2322-
styles: JSCompiler_object_inline_styles_1585,
2323-
bootstrapScripts: JSCompiler_object_inline_bootstrapScripts_1586,
2324-
scripts: JSCompiler_object_inline_scripts_1587,
2325-
bulkPreloads: JSCompiler_object_inline_bulkPreloads_1588,
2326-
preloads: JSCompiler_object_inline_preloads_1589,
2319+
preconnects: JSCompiler_object_inline_preconnects_1586,
2320+
fontPreloads: JSCompiler_object_inline_fontPreloads_1587,
2321+
highImagePreloads: JSCompiler_object_inline_highImagePreloads_1588,
2322+
styles: JSCompiler_object_inline_styles_1589,
2323+
bootstrapScripts: JSCompiler_object_inline_bootstrapScripts_1590,
2324+
scripts: JSCompiler_object_inline_scripts_1591,
2325+
bulkPreloads: JSCompiler_object_inline_bulkPreloads_1592,
2326+
preloads: JSCompiler_object_inline_preloads_1593,
23272327
boundaryResources: null,
23282328
stylesToHoist: !1,
23292329
generateStaticMarkup: generateStaticMarkup
@@ -4930,16 +4930,17 @@ function flushCompletedQueues(request, destination) {
49304930
0 === request.clientRenderedBoundaries.length &&
49314931
0 === request.completedBoundaries.length &&
49324932
((request.flushScheduled = !1),
4933-
(request = request.resumableState),
4934-
request.hasBody &&
4933+
(i = request.resumableState),
4934+
i.hasBody &&
49354935
(destination.push("</"),
49364936
destination.push("body"),
49374937
destination.push(">")),
4938-
request.hasHtml &&
4938+
i.hasHtml &&
49394939
(destination.push("</"),
49404940
destination.push("html"),
49414941
destination.push(">")),
4942-
destination.push(null));
4942+
destination.push(null),
4943+
(request.destination = null));
49434944
}
49444945
}
49454946
function enqueueFlush(request) {
@@ -4948,9 +4949,11 @@ function enqueueFlush(request) {
49484949
0 === request.pingedTasks.length &&
49494950
null !== request.destination
49504951
) {
4951-
var destination = request.destination;
49524952
request.flushScheduled = !0;
4953-
flushCompletedQueues(request, destination);
4953+
var destination = request.destination;
4954+
destination
4955+
? flushCompletedQueues(request, destination)
4956+
: (request.flushScheduled = !1);
49544957
}
49554958
}
49564959
function abort(request, reason) {
@@ -5050,4 +5053,4 @@ exports.renderToString = function (children, options) {
50505053
'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server'
50515054
);
50525055
};
5053-
exports.version = "18.3.0-www-classic-1719e6f1";
5056+
exports.version = "18.3.0-www-classic-abc7431e";

compiled/facebook-www/ReactDOMServer-prod.modern.js

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2287,24 +2287,24 @@ function hoistStylesheetDependency(stylesheet) {
22872287
function createRenderState(resumableState, generateStaticMarkup) {
22882288
var idPrefix = resumableState.idPrefix;
22892289
resumableState = idPrefix + "P:";
2290-
var JSCompiler_object_inline_segmentPrefix_1557 = idPrefix + "S:";
2290+
var JSCompiler_object_inline_segmentPrefix_1561 = idPrefix + "S:";
22912291
idPrefix += "B:";
2292-
var JSCompiler_object_inline_preconnects_1569 = new Set(),
2293-
JSCompiler_object_inline_fontPreloads_1570 = new Set(),
2294-
JSCompiler_object_inline_highImagePreloads_1571 = new Set(),
2295-
JSCompiler_object_inline_styles_1572 = new Map(),
2296-
JSCompiler_object_inline_bootstrapScripts_1573 = new Set(),
2297-
JSCompiler_object_inline_scripts_1574 = new Set(),
2298-
JSCompiler_object_inline_bulkPreloads_1575 = new Set(),
2299-
JSCompiler_object_inline_preloads_1576 = {
2292+
var JSCompiler_object_inline_preconnects_1573 = new Set(),
2293+
JSCompiler_object_inline_fontPreloads_1574 = new Set(),
2294+
JSCompiler_object_inline_highImagePreloads_1575 = new Set(),
2295+
JSCompiler_object_inline_styles_1576 = new Map(),
2296+
JSCompiler_object_inline_bootstrapScripts_1577 = new Set(),
2297+
JSCompiler_object_inline_scripts_1578 = new Set(),
2298+
JSCompiler_object_inline_bulkPreloads_1579 = new Set(),
2299+
JSCompiler_object_inline_preloads_1580 = {
23002300
images: new Map(),
23012301
stylesheets: new Map(),
23022302
scripts: new Map(),
23032303
moduleScripts: new Map()
23042304
};
23052305
return {
23062306
placeholderPrefix: resumableState,
2307-
segmentPrefix: JSCompiler_object_inline_segmentPrefix_1557,
2307+
segmentPrefix: JSCompiler_object_inline_segmentPrefix_1561,
23082308
boundaryPrefix: idPrefix,
23092309
startInlineScript: "<script>",
23102310
htmlChunks: null,
@@ -2316,14 +2316,14 @@ function createRenderState(resumableState, generateStaticMarkup) {
23162316
importMapChunks: [],
23172317
preloadChunks: [],
23182318
hoistableChunks: [],
2319-
preconnects: JSCompiler_object_inline_preconnects_1569,
2320-
fontPreloads: JSCompiler_object_inline_fontPreloads_1570,
2321-
highImagePreloads: JSCompiler_object_inline_highImagePreloads_1571,
2322-
styles: JSCompiler_object_inline_styles_1572,
2323-
bootstrapScripts: JSCompiler_object_inline_bootstrapScripts_1573,
2324-
scripts: JSCompiler_object_inline_scripts_1574,
2325-
bulkPreloads: JSCompiler_object_inline_bulkPreloads_1575,
2326-
preloads: JSCompiler_object_inline_preloads_1576,
2319+
preconnects: JSCompiler_object_inline_preconnects_1573,
2320+
fontPreloads: JSCompiler_object_inline_fontPreloads_1574,
2321+
highImagePreloads: JSCompiler_object_inline_highImagePreloads_1575,
2322+
styles: JSCompiler_object_inline_styles_1576,
2323+
bootstrapScripts: JSCompiler_object_inline_bootstrapScripts_1577,
2324+
scripts: JSCompiler_object_inline_scripts_1578,
2325+
bulkPreloads: JSCompiler_object_inline_bulkPreloads_1579,
2326+
preloads: JSCompiler_object_inline_preloads_1580,
23272327
boundaryResources: null,
23282328
stylesToHoist: !1,
23292329
generateStaticMarkup: generateStaticMarkup
@@ -4865,16 +4865,17 @@ function flushCompletedQueues(request, destination) {
48654865
0 === request.clientRenderedBoundaries.length &&
48664866
0 === request.completedBoundaries.length &&
48674867
((request.flushScheduled = !1),
4868-
(request = request.resumableState),
4869-
request.hasBody &&
4868+
(i = request.resumableState),
4869+
i.hasBody &&
48704870
(destination.push("</"),
48714871
destination.push("body"),
48724872
destination.push(">")),
4873-
request.hasHtml &&
4873+
i.hasHtml &&
48744874
(destination.push("</"),
48754875
destination.push("html"),
48764876
destination.push(">")),
4877-
destination.push(null));
4877+
destination.push(null),
4878+
(request.destination = null));
48784879
}
48794880
}
48804881
function enqueueFlush(request) {
@@ -4883,9 +4884,11 @@ function enqueueFlush(request) {
48834884
0 === request.pingedTasks.length &&
48844885
null !== request.destination
48854886
) {
4886-
var destination = request.destination;
48874887
request.flushScheduled = !0;
4888-
flushCompletedQueues(request, destination);
4888+
var destination = request.destination;
4889+
destination
4890+
? flushCompletedQueues(request, destination)
4891+
: (request.flushScheduled = !1);
48894892
}
48904893
}
48914894
function abort(request, reason) {
@@ -4985,4 +4988,4 @@ exports.renderToString = function (children, options) {
49854988
'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server'
49864989
);
49874990
};
4988-
exports.version = "18.3.0-www-modern-4a0e1ba5";
4991+
exports.version = "18.3.0-www-modern-75350665";

compiled/facebook-www/ReactDOMServerStreaming-dev.modern.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12838,7 +12838,10 @@ function flushCompletedQueues(request, destination) {
1283812838
}
1283912839
} // We're done.
1284012840

12841-
close(destination);
12841+
close(destination); // We need to stop flowing now because we do not want any async contexts which might call
12842+
// float methods to initiate any flushes after this point
12843+
12844+
stopFlowing(request);
1284212845
}
1284312846
}
1284412847
}
@@ -12883,6 +12886,9 @@ function startFlowing(request, destination) {
1288312886
fatalError(request, error);
1288412887
}
1288512888
}
12889+
function stopFlowing(request) {
12890+
request.destination = null;
12891+
} // This is called to early terminate a request. It puts all pending boundaries in client rendered state.
1288612892

1288712893
function abort(request, reason) {
1288812894
try {

compiled/facebook-www/ReactDOMServerStreaming-prod.modern.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4643,16 +4643,17 @@ function flushCompletedQueues(request, destination) {
46434643
0 === request.clientRenderedBoundaries.length &&
46444644
0 === request.completedBoundaries.length &&
46454645
((request.flushScheduled = !1),
4646-
(request = request.resumableState),
4647-
request.hasBody &&
4646+
(i = request.resumableState),
4647+
i.hasBody &&
46484648
(writeChunk(destination, "</"),
46494649
writeChunk(destination, "body"),
46504650
writeChunk(destination, ">")),
4651-
request.hasHtml &&
4651+
i.hasHtml &&
46524652
(writeChunk(destination, "</"),
46534653
writeChunk(destination, "html"),
46544654
writeChunk(destination, ">")),
4655-
(destination.done = !0));
4655+
(destination.done = !0),
4656+
(request.destination = null));
46564657
}
46574658
}
46584659
function enqueueFlush(request) {

0 commit comments

Comments
 (0)