Closed mcnulty closed 6 months ago
I ran into this issue myself as well. Are you still willing to submit the fix as a PR? If not, I may try sending a PR with that fix with credit.
@mbilker Thanks for the reminder! I had a fix locally that I just submitted in #462.
I also updated the reproducer repo with a branch that shows how the fix can be used in a wrangler project to fix the bug.
Thank you very much! I can confirm the response_body()
works for my use-case as well and also that the Content-Length
header is being set to the correct value.
Is there an existing issue for this?
What version of
workers-rs
are you using?main
What version of
wrangler
are you using?0.0.0-3f61892d
Describe the bug
When streaming an R2 object with a size > 200 MB in size, a Rust based worker exceeds the CPU limit. When I rewrite the same worker in TypeScript, the CPU limit is not exceeded.
I've created a reproducer repository for the issue that can be used to reproduce the issue. I cannot reproduce this issue locally using wrangler. That is, I only run into this issue when deploying the worker and accessing a large file stored in the associated R2 bucket.
From what I can tell, the code that leads to the issue is:
Looking further in the workers-rs source, I think the underlying issue is that
r2::ObjectBody
returns a Rust stream that wraps the nativeReadableStream
fromr2::ObjectBody::stream
.Response::from_stream
then converts the Rust stream into aReadableStream
, which is then passed to the nativeweb_sys::Response::new_with_opt_readable_stream
. I think this leads to invocation of the Rust wasm code while streaming chunks of the R2 object to the client.To confirm this suspicion, I added the following function to
r2::ObjectBody
to allow aResponseBody
to be created using ther2::ObjectBody
's innerReadableStream
. ThisResponseBody
can then be passed toResponse::from_body
to avoid converting theReadableStream
into a Rust stream and as a result, also avoid the invocation of the Rust code while streaming the R2 object:If this all makes sense, I can go ahead and open a PR with the
response_body
function added tor2::ObjectBody
.Steps To Reproduce
r2-download-bug
npm install
npm run gen-test-file
rclone copy --progress bucket-src/200MB-file r2:r2-download-bug/
npm run deploy
npx wrangler tail
curl -v https://r2-download-bug.$DOMAIN.workers.dev/200MB-file > ./200MB-file
After this last step, you should see the following: