-
Notifications
You must be signed in to change notification settings - Fork 20
Open
Description
Hey all,
I'm experiencing an issue streaming results from a container to a client.
I have a reproduction of the following issue with instructions: https://github.com/Ehesp/cf-containers-repro
My container (a Bun server) had an endpoint which streams back a 10 messages every second:
app.post("/stream", async (c) => {
let remaining = 10;
const stream = new ReadableStream({
async start(controller) {
while (remaining > 0) {
console.log("enqueue:", remaining);
controller.enqueue(
new TextEncoder().encode(`Hello, world! ${remaining}\n\n`)
);
await new Promise((resolve) => setTimeout(resolve, 1000));
remaining--;
}
console.log("closing stream");
controller.close();
},
});
return new Response(stream, {
headers: {
"Content-Type": "text/plain",
"Transfer-Encoding": "chunked",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Content-Encoding": "identity",
},
});
});Inside the DO, this is proxied via containerFetch:
async stream() {
const response = await this.containerFetch("http://container/stream", {
method: "POST",
body: JSON.stringify({
message: "Hello, world!",
}),
});
return new Response(response.body, {
headers: response.headers,
status: response.status,
statusText: response.statusText,
});
}My worker then proxies:
app.post("/stream", async (c) => {
const container = getContainer(c.env.MY_CONTAINER);
const response = await container.stream();
return new Response(response.body, {
headers: response.headers,
status: response.status,
statusText: response.statusText,
});
});My Node client script:
async function main() {
const response = await fetch("http://localhost:8787/stream", {
duplex: "half",
method: "POST",
body: JSON.stringify({}),
headers: {
"Accept-Encoding": "identity", // Tell the worker to not compress the stream
},
});
console.log("client headers", Object.fromEntries(response.headers));
for await (const chunk of response.body) {
console.log("Client>", new TextDecoder().decode(chunk));
}
}
main().catch((error) => {
console.error(error);
});I constantly get inconsistent results, either the whole thing streams (less often) or some results:
Run 1:
client headers {
'cache-control': 'no-cache',
'content-encoding': 'identity',
'content-type': 'text/plain',
date: 'Thu, 17 Jul 2025 08:54:32 GMT',
'transfer-encoding': 'chunked'
}
Client> Hello, world! 10
Client> Hello, world! 9
Run 2:
client headers {
'cache-control': 'no-cache',
'content-encoding': 'identity',
'content-type': 'text/plain',
date: 'Thu, 17 Jul 2025 08:58:56 GMT',
'transfer-encoding': 'chunked'
}
Client> Hello, world! 10
Client> Hello, world! 9
Client> Hello, world! 8
Client> Hello, world! 7
Client> Hello, world! 6
Client> Hello, world! 5
Client> Hello, world! 4
I'm totally unsure where the issue lies, but I've not had this issue when the origin isn't a Cloudflare Container.
Metadata
Metadata
Assignees
Labels
No labels