Skip to content

Fix Small Typo: privlaged → privileged#1

Merged
ry merged 1 commit into
denoland:masterfrom
lusbuab:patch-1
May 29, 2018
Merged

Fix Small Typo: privlaged → privileged#1
ry merged 1 commit into
denoland:masterfrom
lusbuab:patch-1

Conversation

@lusbuab

@lusbuab lusbuab commented May 29, 2018

Copy link
Copy Markdown
Contributor

No description provided.

@ry ry left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@ry
ry merged commit 8631e44 into denoland:master May 29, 2018
fewf pushed a commit to fewf/deno that referenced this pull request Feb 7, 2019
add tests and add permissions checks to op_open
@jackedai jackedai mentioned this pull request May 9, 2020
aslilac added a commit that referenced this pull request Jun 23, 2022
castarco pushed a commit to castarco/deno that referenced this pull request Aug 3, 2024
hardfist referenced this pull request in hardfist/deno Aug 7, 2024
losfair added a commit that referenced this pull request Aug 14, 2024
nathanwhit added a commit that referenced this pull request Jun 26, 2026
## Summary

A trivial [Hono](https://hono.dev) app served through `Deno.serve` left
a lot of throughput on the table and emitted `transfer-encoding:
chunked` where a fixed `Content-Length` was possible:

```ts
const app = new Hono();
app.use("*", async (c, next) => {
  await next();
  c.header("x-powered-by", "hono");
});
app.get("/", (c) => c.json({ hello: "world", framework: "hono" }));
Deno.serve({ port, hostname: "127.0.0.1" }, app.fetch);
```

Profiling (`samply` + `--v8-flags=--perf-basic-prof`) pinned the
overhead to the middleware's `c.header()` call, which after `await
next()` runs `new Response(oldResponse.body, oldResponse)` to tweak a
header — a very common framework pattern. That exposed three avoidable
costs, fixed here:

1. **Static body downgraded to a stream.** Reading `.body` turns the
fast string body into a `ReadableStream`, so the response is served via
the streaming/chunked path — 3 `__sendto` syscalls/req and no
`Content-Length` (~30% of main-thread time). `extractBody` now recovers
the original static body when a `Response`/`Request` is reconstructed
from an **undisturbed, static-backed** stream, restoring the
single-write fast static path. Genuine streams (and any read/locked
stream) are untouched.

2. **Headers re-validated through webidl.** `fillHeaderList` sent the
already-validated `Headers` init object through the full webidl
`sequence<sequence<ByteString>>` converter, re-validating every entry
(~22% of main-thread time after fix #1). It now copies a `Headers`
instance's entries directly.

3. **Eager body-stream materialization.** The `.body` getter eagerly
built and UTF-8-encoded a `ReadableStream` that recovery immediately
discards. It's now materialized lazily (high-water-mark 0, via the
internal `createReadableStream` that also skips the webidl
`UnderlyingSource` conversion), so the encode only happens on an actual
read.

## Result

`oha -n 1000000 -c 100 --disable-compression`, `--profile=release-lite`:

| | req/s | encoding |
|---|---|---|
| before | 54,899 | chunked |
| + static-body recovery | 79,207 | content-length |
| + Headers fast path | 91,807 | content-length |
| + lazy body stream | **98,637** | content-length |

**+80%** on the same app, with `Content-Length` restored. The remaining
cost is dominated by raw socket I/O (`__sendto` + `__recvfrom` ≈ 42% of
main-thread time) and the inherent cost of constructing
`Response`/`Headers` objects in JS.

## Behavior change

Reconstructing a `Response`/`Request` from another body's stream (`new
Response(other.body, other)`) and serving/consuming it now yields a
`Content-Length` instead of chunked encoding when the source stream was
static-backed and unread. As a side effect, consuming the reconstructed
body no longer disturbs the original stream (the bytes are identical
either way). Genuine `ReadableStream` bodies are unaffected.

## Tests

- `ext/fetch/22_body.js` / `ext/fetch/20_headers.js` changes.
- `tests/unit/serve_test.ts`: the `stream()` helper now builds a
genuinely-opaque stream so the existing length/chunked tests still
exercise the chunked path; added `recoveredStaticStreamBody` covering
the new fast path.
- `unit::{streams,body,headers,response,request,fetch,serve}_test` all
pass; `tools/format.js` + `tools/lint.js --js` clean.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants