Igor Zinkovsky
7043521ce8
fix(ext/kv): don't panic if listening on queues and KV is not closed ( #20317 )
...
fixes #20312
2023-08-31 14:04:14 +02:00
Bartek Iwańczuk
430c1f635a
fix(node/http): don't leak resources on destroyed request ( #20040 )
...
Closes https://github.com/denoland/deno/issues/19828
2023-08-31 14:04:14 +02:00
Yoshiya Hinosawa
7e14fe4c02
fix(ext/node): fix argv[1] in Worker ( #20305 )
2023-08-31 14:04:08 +02:00
Matt Mastracci
9320f37d6b
fix(ext/node): shared global buffer unlock correctness fix ( #20314 )
...
The fix for #20188 was not entirely correct -- we were unlocking the
global buffer incorrectly. This PR introduces a lock state that ensures
we only unlock a lock we have taken out.
2023-08-31 14:04:07 +02:00
Matt Mastracci
f03ffaf540
fix(ext/http): don't panic on stream responses in cancelled requests ( #20316 )
...
When a TCP connection is force-closed (ie: browser refresh), the
underlying future we pass to Hyper is dropped which may cause us to try
to drop the body resource while the OpState lock is still held.
Preconditions for this bug to trigger:
- The body resource must have been taken
- The response must return a resource (which requires us to take the
OpState lock)
- The TCP connection must have been dropped before this
Fixes #20315 and #20298
2023-08-31 14:04:07 +02:00
Jonathan Rezende
8b34936788
fix(network): adjust Listener type params ( #18642 )
...
Fixes https://github.com/denoland/deno/issues/18635
2023-08-31 14:04:06 +02:00
林炳权
51befb9bb5
chore: update to Rust 1.72 ( #20258 )
...
<!--
Before submitting a PR, please read https://deno.com/manual/contributing
1. Give the PR a descriptive title.
Examples of good title:
- fix(std/http): Fix race condition in server
- docs(console): Update docstrings
- feat(doc): Handle nested reexports
Examples of bad title:
- fix #7123
- update docs
- fix bugs
2. Ensure there is a related issue and it is referenced in the PR text.
3. Ensure there are tests that cover the changes.
4. Ensure `cargo test` passes.
5. Ensure `./tools/format.js` passes without changing files.
6. Ensure `./tools/lint.js` passes.
7. Open as a draft PR if your work is still in progress. The CI won't
run
all steps, but you can add '[ci]' to a commit message to force it to.
8. If you would like to run the benchmarks on the CI, add the 'ci-bench'
label.
-->
As the title.
---------
Co-authored-by: Matt Mastracci <matthew@mastracci.com>
2023-08-31 14:02:40 +02:00
Igor Zinkovsky
669b6fd692
fix(kv) increase number of allowed mutations in atomic ( #20126 )
...
fixes #19741
Impose a limit on the total atomic payload size
2023-08-31 14:02:40 +02:00
Divy Srivastava
999bc870f6
fix(node): propagate create cipher errors ( #20280 )
...
Fixes https://github.com/denoland/deno/issues/19002
2023-08-31 14:02:40 +02:00
Matt Mastracci
d34c23b8f3
fix(ext/tls): upgrade webpki version ( #20285 )
...
This removes a webpki version that was showing up as vulnerable to
https://github.com/briansmith/webpki/issues/69 .
Needed to upgrade `reqwest` as part of this.
2023-08-31 14:02:39 +02:00
VlkrS
cda9601d2a
feat(node): use i32 for priority_t on MacOS and {Free,Open}BSD ( #20286 )
...
Reference from the FreeBSD port
3afa24c6e3/www/deno/files/patch-ext_node_ops_os.rs
2023-08-31 14:02:39 +02:00
Heyang Zhou
a42ac7f686
feat(ext/kv): connect to remote database ( #20178 )
...
This patch adds a `remote` backend for `ext/kv`. This supports
connection to Deno Deploy and potentially other services compatible with
the KV Connect protocol.
2023-08-31 14:01:18 +02:00
denobot
55029c7261
1.36.3 ( #20268 )
...
Bumped versions for 1.36.3
Co-authored-by: mmastrac <mmastrac@users.noreply.github.com>
2023-08-24 10:01:52 -06:00
Matt Mastracci
09a1fda8e4
fix(ext/web): add stream tests to detect v8slice split bug ( #20253 )
...
Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
2023-08-24 09:01:07 -06:00
Matt Mastracci
f1dc054d52
fix(ext/web): better handling of errors in resourceForReadableStream ( #20238 )
...
Improves error handling when the Resource is closed in various phases of
the ReadableStream. Ensure that we send a consistent `cancel` reason.
2023-08-24 09:00:35 -06:00
Matt Mastracci
3e9fb8aafd
fix(ext/node): simultaneous reads can leak into each other ( #20223 )
...
Reported in #20188
This was caused by re-use of a global buffer `BUF` during simultaneous
async reads.
2023-08-24 09:00:30 -06:00
denobot
a7f5244a72
1.36.2 ( #20222 )
...
Bumped versions for 1.36.2
Co-authored-by: Divy Srivastava <dj.srivastava23@gmail.com>
2023-08-21 19:09:22 +05:30
David Sherret
1dd571578c
refactor: upgrade deno_ast 0.28 and deno_semver 0.4 ( #20193 )
2023-08-21 18:23:28 +05:30
Matt Mastracci
431289faaa
fix(ext/http): ensure request body resource lives as long as response is alive ( #20206 )
...
Deno.serve's fast streaming implementation was not keeping the request
body resource ID alive. We were taking the `Rc<Resource>` from the
resource table during the response, so a hairpin duplex response that
fed back the request body would work.
However, if any JS code attempted to read from the request body (which
requires the resource ID to be valid), the response would fail with a
difficult-to-diagnose "EOF" error.
This was affecting more complex duplex uses of `Deno.fetch` (though as
far as I can tell was unreported).
Simple test:
```ts
const reader = request.body.getReader();
return new Response(
new ReadableStream({
async pull(controller) {
const { done, value } = await reader.read();
if (done) {
controller.close();
} else {
controller.enqueue(value);
}
},
}),
```
And then attempt to use the stream in duplex mode:
```ts
async function testDuplex(
reader: ReadableStreamDefaultReader<Uint8Array>,
writable: WritableStreamDefaultWriter<Uint8Array>,
) {
await writable.write(new Uint8Array([1]));
const chunk1 = await reader.read();
assert(!chunk1.done);
assertEquals(chunk1.value, new Uint8Array([1]));
await writable.write(new Uint8Array([2]));
const chunk2 = await reader.read();
assert(!chunk2.done);
assertEquals(chunk2.value, new Uint8Array([2]));
await writable.close();
const chunk3 = await reader.read();
assert(chunk3.done);
}
```
In older versions of Deno, this would just lock up. I believe after
23ff0e722e
, it started throwing a more
explicit error:
```
httpServerStreamDuplexJavascript => ./cli/tests/unit/serve_test.ts:1339:6
error: TypeError: request or response body error: error reading a body from connection: Connection reset by peer (os error 54)
at async Object.pull (ext:deno_web/06_streams.js:810:27)
```
2023-08-21 18:23:28 +05:30
Bartek Iwańczuk
698776f137
perf(ext/event): always set timeStamp to 0 ( #20191 )
...
```js
Deno.bench(function eventNew() {
new Event("foo");
});
```
<b>main</b>
```
./target/release/deno bench event_bench.js
cpu: Apple M1 Max
runtime: deno 1.36.1 (aarch64-apple-darwin)
file:///Users/ib/dev/deno/event_bench.js
benchmark time (avg) iter/s (min … max) p75 p99 p995
--------------------------------------------------------------- -----------------------------
eventNew 36.43 ns/iter 27,451,874.9 (35.15 ns … 46.98 ns) 37.68 ns 40.7 ns 41.69 ns
```
<b>this PR</b>
```
./target/release/deno bench event_bench.js
cpu: Apple M1 Max
runtime: deno 1.36.1 (aarch64-apple-darwin)
file:///Users/ib/dev/deno/event_bench.js
benchmark time (avg) iter/s (min … max) p75 p99 p995
--------------------------------------------------------------- -----------------------------
eventNew 13.71 ns/iter 72,958,970.0 (12.85 ns … 31.79 ns) 15.11 ns 16.49 ns 17.5 ns
```
Towards #20167
2023-08-21 18:23:28 +05:30
Marcos Casagrande
627499177f
perf(ext/event): optimize addEventListener options converter ( #20203 )
...
This PR optimizes `addEventListener` by replacing
`webidl.createDictionaryConverter("AddEventListenerOptions", ...)` with
a custom options parsing function to avoid the overhead of `webidl`
methods
**this PR**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.1 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
---------------------------------------------------------------------------------------------------- -----------------------------
addEventListener options converter (undefined) 4.87 ns/iter 205,248,660.8 (4.7 ns … 13.18 ns) 4.91 ns 5.4 ns 5.6 ns
addEventListener options converter (signal) 13.02 ns/iter 76,782,031.2 (11.74 ns … 18.84 ns) 13.08 ns 16.22 ns 16.57 ns
```
**main**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.1 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
---------------------------------------------------------------------------------------------------- -----------------------------
addEventListener options converter (undefined) 108.36 ns/iter 9,228,688.6 (103.5 ns … 129.88 ns) 109.69 ns 115.61 ns 125.28 ns
addEventListener options converter (signal) 134.03 ns/iter 7,460,878.1 (129.14 ns … 144.54 ns) 135.68 ns 141.13 ns 144.1 ns
```
```js
const tg = new EventTarget();
const signal = new AbortController().signal;
Deno.bench("addEventListener options converter (undefined)", () => {
tg.addEventListener("foo", null); // null callback to only bench options converter
});
Deno.bench("addEventListener options converter (signal)", () => {
tg.addEventListener("foo", null, { signal });
});
```
Towards https://github.com/denoland/deno/issues/20167
2023-08-21 18:23:28 +05:30
Marcos Casagrande
987c3d6aa8
perf(ext/event): replace ReflectHas with object lookup ( #20190 )
...
This PR optimizes event dispatch by replacing `ReflectHas` with object
lookup. I also made `isSlottable` return `false` since AFAIK there
aren't any slottables nodes in Deno
**This PR**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.1 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
--------------------------------------------------------------------- -----------------------------
event dispatch 80.46 ns/iter 12,428,739.4 (73.84 ns … 120.07 ns) 81.82 ns 86.34 ns 91.18 ns
```
**main**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.1 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
--------------------------------------------------------------------- -----------------------------
event dispatch 102.66 ns/iter 9,741,319.6 (96.66 ns … 132.88 ns) 104.18 ns 114.58 ns 118.45 ns
```
```js
const tg = new EventTarget();
const ev = new Event("foo");
const listener = () => {};
tg.addEventListener("foo", listener);
Deno.bench("event dispatch ", () => {
tg.dispatchEvent(ev);
});
```
towards https://github.com/denoland/deno/issues/20167
2023-08-21 18:23:27 +05:30
Bartek Iwańczuk
fc6a537c2b
fix(node/http): emit error when addr in use ( #20200 )
...
Closes https://github.com/denoland/deno/issues/20186
2023-08-21 18:23:27 +05:30
Heyang Zhou
2150ae7d60
feat(ext/kv): key expiration ( #20091 )
...
Co-authored-by: Luca Casonato <hello@lcas.dev>
2023-08-21 18:23:27 +05:30
David Sherret
1b4c910075
fix(npm): do not panic providing file url to require.resolve paths ( #20182 )
...
Closes #19922
2023-08-21 18:23:27 +05:30
Matt Mastracci
32947e5ea5
feat(ext/web): resourceForReadableStream ( #20180 )
...
Extracted from fast streams work.
This is a resource wrapper for `ReadableStream`, allowing us to treat
all `ReadableStream` instances as resources, and remove special paths in
both `fetch` and `serve`.
Performance with a ReadableStream response yields ~18% improvement:
```
return new Response(new ReadableStream({
start(controller) {
controller.enqueue(new Uint8Array([104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]));
controller.close();
}
})
```
This patch:
```
12:36 $ third_party/prebuilt/mac/wrk http://localhost:8080
Running 10s test @ http://localhost:8080
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 99.96us 100.03us 6.65ms 98.84%
Req/Sec 47.73k 2.43k 51.02k 89.11%
959308 requests in 10.10s, 117.10MB read
Requests/sec: 94978.71
Transfer/sec: 11.59MB
```
main:
```
Running 10s test @ http://localhost:8080
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 163.03us 685.51us 19.73ms 99.27%
Req/Sec 39.50k 3.98k 66.11k 95.52%
789582 requests in 10.10s, 82.83MB read
Requests/sec: 78182.65
Transfer/sec: 8.20MB
```
2023-08-21 18:23:27 +05:30
Heyang Zhou
15f57a8535
fix(ext/kv): retry transaction on SQLITE_BUSY
errors ( #20189 )
...
Properly handle the `SQLITE_BUSY` error code by retrying the
transaction.
Also wraps database initialization logic in a transaction to protect
against incomplete/concurrent initializations.
Fixes https://github.com/denoland/deno/issues/20116 .
2023-08-21 18:23:27 +05:30
Marcos Casagrande
3b4efd339d
perf(ext/event): optimize Event constructor ( #20181 )
...
This PR optimizes `Event` constructor
- ~Added a fast path for empty `eventInitDict`~ Removed `EventInit`
dictionary converter
- Don't make `isTrusted` a
[LegacyUnforgeable](https://webidl.spec.whatwg.org/#LegacyUnforgeable )
property. Doing so makes it non-spec compliant but calling
`Object/Reflect.defineProperty` on the constructor is a big bottleneck.
Node did the same a few months ago
https://github.com/nodejs/node/pull/46974 . In my opinion, the
performance gains are worth deviating from the spec for a
browser-related property.
**This PR**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.1 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
------------------------------------------------------------------------------- -----------------------------
event constructor no init 36.69 ns/iter 27,257,504.6 (33.36 ns … 42.45 ns) 37.71 ns 39.61 ns 40.07 ns
event constructor 36.7 ns/iter 27,246,776.6 (33.35 ns … 56.03 ns) 37.73 ns 40.14 ns 41.74 ns
```
**main**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.1 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
------------------------------------------------------------------------------- -----------------------------
event constructor no init 380.48 ns/iter 2,628,275.8 (366.66 ns … 399.39 ns) 384.58 ns 398.27 ns 399.39 ns
event constructor 480.33 ns/iter 2,081,882.6 (466.67 ns … 503.47 ns) 484.27 ns 501.28 ns 503.47 ns
```
```js
Deno.bench("event constructor no init", () => {
const event = new Event("foo");
});
Deno.bench("event constructor", () => {
const event = new Event("foo", { bubbles: true, cancelable: false });
});
```
towards https://github.com/denoland/deno/issues/20167
2023-08-21 18:23:27 +05:30
Leo Kettmeir
3dab9ead27
fix: release ReadeableStream in fetch ( #17365 )
...
Fixes #16648
---------
Co-authored-by: Aapo Alasuutari <aapo.alasuutari@gmail.com>
2023-08-21 18:23:27 +05:30
Marcos Casagrande
75ea2c1b20
perf(ext/urlpattern): optimize URLPattern.exec ( #20170 )
...
This PR optimizes `URLPattern.exec`
- Use component keys from constructor instead of calling it on every
`.exec`. AFAIK keys should always be
`protocol`,`username`,`password`,`hostname`,`port`,`pathname`,`search`,`hash`.
Haven't looked much into it but I think it's safe to define these
outside the constructor as well.
- Add a fast path for `/^$/u` (default regexp) and empty input
- Replaced `ArrayPrototypeMap` & `ObjectFromEntries` with a `for` loop.
**this PR**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.1 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
--------------------------------------------------------------- -----------------------------
exec 1 2.17 µs/iter 461,022.8 (2.14 µs … 2.27 µs) 2.18 µs 2.27 µs 2.27 µs
exec 2 4.13 µs/iter 242,173.4 (4.08 µs … 4.27 µs) 4.15 µs 4.27 µs 4.27 µs
exec 3 2.55 µs/iter 391,508.1 (2.53 µs … 2.68 µs) 2.56 µs 2.68 µs 2.68 µs
```
**main**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.1 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
--------------------------------------------------------------- -----------------------------
exec 1 2.45 µs/iter 408,092.4 (2.41 µs … 2.55 µs) 2.46 µs 2.55 µs 2.55 µs
exec 2 4.41 µs/iter 226,706.0 (3.49 µs … 399.56 µs) 4.39 µs 5.49 µs 6.07 µs
exec 3 2.99 µs/iter 334,833.4 (2.94 µs … 3.21 µs) 2.99 µs 3.21 µs 3.21 µs
```
2023-08-21 18:23:27 +05:30
Evan
08b9f920f6
fix(ext/node): allow for the reassignment of userInfo() on Windows ( #20165 )
...
The goal of this PR is to address issue #20106 where a `TypeError`
occurs when the variables `uid` and `gid` from `userInfo()` in `node:os`
are reassigned if the user is on Windows. Both `uid` and `gid` are
marked as `const` therefore producing a `TypeError` when the two are
reassigned.
This PR achieves that goal by marking `uid` and `gid` as `let`
2023-08-21 18:23:27 +05:30
Matt Mastracci
851e08bd1f
feat(ext/node): eagerly bootstrap node ( #20153 )
...
To fix bugs around detection of when node emulation is required, we will
just eagerly initialize it. The improvements we make to reduce the
impact of the startup time:
- [x] Process stdin/stdout/stderr are lazily created
- [x] node.js global proxy no longer allocates on each access check
- [x] Process checks for `beforeExit` listeners before doing expensive
shutdown work
- [x] Process should avoid adding global event handlers until listeners
are added
Benchmarking this PR (`89de7e1ff`) vs main (`41cad2179`)
```
12:36 $ third_party/prebuilt/mac/hyperfine --warmup 100 -S none './deno-41cad2179 run ./empty.js' './deno-89de7e1ff run ./empty.js'
Benchmark 1: ./deno-41cad2179 run ./empty.js
Time (mean ± σ): 24.3 ms ± 1.6 ms [User: 16.2 ms, System: 6.0 ms]
Range (min … max): 21.1 ms … 29.1 ms 115 runs
Benchmark 2: ./deno-89de7e1ff run ./empty.js
Time (mean ± σ): 24.0 ms ± 1.4 ms [User: 16.3 ms, System: 5.6 ms]
Range (min … max): 21.3 ms … 28.6 ms 126 runs
```
Fixes https://github.com/denoland/deno/issues/20142
Fixes https://github.com/denoland/deno/issues/15826
Fixes https://github.com/denoland/deno/issues/20028
2023-08-21 18:23:27 +05:30
Marcos Casagrande
578936b490
perf(ext/node): optimize http headers ( #20163 )
...
This PR optimizes Node's `IncomingMessageForServer.headers` by replacing
`Object.fromEntries()` with a loop and `headers.entries` with
`headersEntries` which returns the internal array directly instead of an
iterator
## Benchmarks
Using `wrk` with 5 headers
```
wrk -d 10s --latency -H "X-Deno: true" -H "Accept: application/json" -H "X-Foo: bar" -H "User-Agent: wrk" -H "Accept-Encoding: gzip, br" http://127.0.0.1:3000
```
**this PR**
```
Running 10s test @ http://127.0.0.1:3000
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 167.53us 136.89us 2.75ms 97.33%
Req/Sec 31.98k 1.38k 36.39k 70.30%
Latency Distribution
50% 134.00us
75% 191.00us
90% 234.00us
99% 544.00us
642548 requests in 10.10s, 45.96MB read
Requests/sec: 63620.36
Transfer/sec: 4.55MB
```
**main**
```
Running 10s test @ http://127.0.0.1:3000
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 181.31us 132.54us 3.79ms 97.13%
Req/Sec 29.21k 1.45k 32.93k 79.21%
Latency Distribution
50% 148.00us
75% 198.00us
90% 261.00us
99% 545.00us
586939 requests in 10.10s, 41.98MB read
Requests/sec: 58114.01
Transfer/sec: 4.16MB
```
```js
import express from "npm:express";
const app = express();
app.get("/", function (req, res) {
req.headers;
res.end();
});
app.listen(3000);
```
2023-08-21 18:23:27 +05:30
Marcos Casagrande
7895d154c3
fix(ext/fetch): clone second branch chunks in Body.clone() ( #20057 )
...
This PR makes `Body.clone()` spec compliant:
https://fetch.spec.whatwg.org/#concept-body-clone
> 1, Let « out1, out2 » be the result of
[teeing](https://streams.spec.whatwg.org/#readablestream-tee ) body’s
[stream](https://fetch.spec.whatwg.org/#concept-body-stream ).
> ...
> To tee a
[ReadableStream](https://streams.spec.whatwg.org/#readablestream )
stream, return ?
[ReadableStreamTee](https://streams.spec.whatwg.org/#readable-stream-tee )(stream,
true).
---
Closes #10994
2023-08-21 18:23:27 +05:30
Bartek Iwańczuk
6a5b02bc79
fix(require): use canonicalized path for loading content ( #20133 )
2023-08-21 18:23:27 +05:30
Evan
4001fad25f
fix(ext/net): implement a graceful error on an invalid SSL certificate ( #20157 )
...
The goal of this PR is to address issue #19520 where Deno panics when
encountering an invalid SSL certificate.
This PR achieves that goal by removing an `.expect()` statement and
implementing a match statement on `tsl_config` (found in
[/ext/net/ops_tsl.rs](e071382768/ext/net/ops_tls.rs (L1058)
))
to check whether the desired configuration is valid
---------
Co-authored-by: Matt Mastracci <matthew@mastracci.com>
2023-08-21 18:23:27 +05:30
Marcos Casagrande
e77d55839d
perf(ext/headers): optimize headers iterable ( #20155 )
...
This PR makes more optimizations to headers iterable by removing
`ObjectEntries` which was consistently prominent in the flame graph when
benchmarking an express server.
**this PR**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.1 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
------------------------------------------------------------------ -----------------------------
headers iter 9.6 µs/iter 104,134.1 (8.74 µs … 131.31 µs) 9.47 µs 12.61 µs 17.81 µs
```
**main**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.1 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
------------------------------------------------------------------ -----------------------------
headers iter 12.87 µs/iter 77,675.9 (11.97 µs … 132.34 µs) 12.76 µs 16.49 µs 26.4 µs
```
```js
const headers = new Headers({
"Content-Type": "application/json",
"X-Content-Type": "application/json",
"Date": "Thu, 14 Aug 2023 17:45:10 GMT",
"X-Deno": "Deno",
"Powered-By": "Deno",
"Content-Encoding": "gzip",
"Set-Cookie": "__Secure-ID=123; Secure; Domain=example.com",
"Content-Length": "150",
"Vary": "Accept-Encoding, Accept, X-Requested-With",
});
Deno.bench('headers iter', () => {
[...headers]
})
```
2023-08-21 18:23:27 +05:30
Marcos Casagrande
049aebee34
perf(ext/node): cache IncomingMessageForServer.headers
( #20147 )
...
This PR adds caching to node's `req.headers`
```js
import express from "npm:express";
const app = express();
app.get("/", function (req, res) {
const ua = req.header("User-Agent");
const auth = req.header("Authorization");
const type = req.header("Content-Type");
const ip = req.header("X-Forwarded-For");
res.end();
});
app.listen(3000);
```
**this PR**
```
wrk -d 10s --latency http://127.0.0.1:3000
Running 10s test @ http://127.0.0.1:3000
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 155.64us 152.14us 5.74ms 97.39%
Req/Sec 35.00k 1.97k 39.10k 80.69%
Latency Distribution
50% 123.00us
75% 172.00us
90% 214.00us
99% 563.00us
703420 requests in 10.10s, 50.31MB read
Requests/sec: 69648.45
Transfer/sec: 4.98MB
```
**main**
```
wrk -d 10s --latency http://127.0.0.1:3000
Running 10s test @ http://127.0.0.1:3000
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 217.95us 786.89us 26.26ms 98.23%
Req/Sec 32.32k 2.54k 37.19k 87.13%
Latency Distribution
50% 130.00us
75% 191.00us
90% 232.00us
99% 1.88ms
649411 requests in 10.10s, 46.45MB read
Requests/sec: 64300.44
Transfer/sec: 4.60MB
```
2023-08-21 18:23:27 +05:30
Matt Mastracci
3abe95baf4
chore: deno_core -> 0.201.0 ( #20135 )
2023-08-21 18:23:27 +05:30
Marcos Casagrande
4e08665973
perf(ext/request): optimize validate and normalize HTTP method ( #20143 )
...
This PR optimizes `Request` constructor init method step. It doubles the
speed for known lowercased methods. I also added `PATCH` to known
methods
**this patch**
```
benchmark time (avg) iter/s (min … max) p75 p99 p995
---------------------------------------------------------------------------- -----------------------------
method: GET 1.49 µs/iter 669,336.9 (1.35 µs … 2.02 µs) 1.54 µs 2.02 µs 2.02 µs
method: PATCH 1.85 µs/iter 540,921.5 (1.65 µs … 2.02 µs) 1.91 µs 2.02 µs 2.02 µs
method: get 1.49 µs/iter 669,067.9 (1.28 µs … 1.69 µs) 1.55 µs 1.69 µs 1.69 µs
```
**main**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.1 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
---------------------------------------------------------------------------- -----------------------------
method: GET 1.5 µs/iter 665,232.3 (1.3 µs … 2.02 µs) 1.54 µs 2.02 µs 2.02 µs
method: PATCH 2.47 µs/iter 404,052.7 (2.06 µs … 4.05 µs) 2.51 µs 4.05 µs 4.05 µs
method: get 3 µs/iter 333,277.2 (2.72 µs … 4.04 µs) 3.05 µs 4.04 µs 4.04 µs
```
```js
Deno.bench("method: GET", () => {
const r = new Request("https://deno.land ", {
method: "GET",
});
});
Deno.bench("method: PATCH", () => {
const r = new Request("https://deno.land ", {
method: "PATCH",
body: '{"foo": "bar"}',
});
});
Deno.bench("method: get", () => {
const r = new Request("https://deno.land ", {
method: "get",
});
});
```
2023-08-21 18:23:27 +05:30
Marcos Casagrande
d0525dd692
perf(ext/headers): use regex.test instead of .exec ( #20125 )
...
This PR improves the performance of `Headers.get` by using `Regex.test`
instead of `.exec`. Also replaced the `Map` used for caching with an
object which is a bit faster
**This patch**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.1 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
----------------------------------------------------------------------- -----------------------------
Headers.get 124.71 ns/iter 8,018,687.3 (115.11 ns … 265.66 ns) 126.05 ns 136.12 ns 142.37 ns
```
**1.36.1**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.0 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
----------------------------------------------------------------------- -----------------------------
Headers.get 218.91 ns/iter 4,568,172.3 (165.37 ns … 264.44 ns) 241.62 ns 260.94 ns 262.67 ns
```
```js
const headers = new Headers({
"Content-Type": "application/json",
"Date": "Thu, 10 Aug 2023 07:45:10 GMT",
"X-Deno": "Deno",
"Powered-By": "Deno",
"Content-Encoding": "gzip",
"Set-Cookie": "__Secure-ID=123; Secure; Domain=example.com",
"Content-Length": "150",
"Vary": "Accept-Encoding, Accept, X-Requested-With",
});
Deno.bench("Headers.get", () => {
headers.get("x-deno");
});
```
2023-08-21 18:23:27 +05:30
Marcos Casagrande
aaa3608cc1
perf(ext/headers): cache iterableHeaders for immutable Headers ( #20132 )
...
This PR caches `_iterableHeaders` for immutable `Headers` increasing the
performance of `fetch` & server if headers are iterated.
Should close #19466
I only cached immutable headers to address this comment
https://github.com/denoland/deno/issues/19466#issuecomment-1589892373
since I didn't find any occurrence of header mutation on immutable
headers. We can discuss caching for non-immutable, but I think this is a
great first step.
## BENCHMARK
### Server
```js
const addr = Deno.args[0] ?? "127.0.0.1:4500";
const [hostname, port] = addr.split(":");
const { serve } = Deno;
serve({ hostname, port: Number(port), reusePort: true }, (req) => {
const headers = [...req.headers]; // req.headers are immutable, cannot set/append/delete
return new Response("ok");
});
```
Used `wrk` with 5 headers
```
wrk -d 10s --latency -H "X-Deno: true" -H "Accept: application/json" -H "X-Foo: bar" -H "User-Agent: wrk" -H "Accept-Encoding: gzip, br" http://127.0.0.1:4500
```
**This patch**
```
Running 10s test @ http://127.0.0.1:4500
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 70.18us 22.89us 679.00us 81.37%
Req/Sec 71.55k 9.69k 82.18k 89.60%
Latency Distribution
50% 59.00us
75% 89.00us
90% 98.00us
99% 159.00us
1437891 requests in 10.10s, 193.35MB read
Requests/sec: 142369.83
Transfer/sec: 19.14MB
```
**main**
```
Running 10s test @ http://127.0.0.1:4500
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 112.78us 36.47us 2.09ms 77.99%
Req/Sec 44.30k 1.65k 49.14k 74.26%
Latency Distribution
50% 99.00us
75% 136.00us
90% 162.00us
99% 213.00us
890588 requests in 10.10s, 118.91MB read
Requests/sec: 88176.37
Transfer/sec: 11.77MB
```
### fetch
```js
const res = await fetch('http://127.0.0.1:4500 ');
Deno.bench("Headers iterator", () => {
const i = [...res.headers]; // res.headers are immutable, cannot set/append/delete
});
```
**this patch**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.1 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
---------------------------------------------------------------------- -----------------------------
Headers iterator 329.5 ns/iter 3,034,909.0 (318.55 ns … 364.34 ns) 331.1 ns 355.72 ns 364.34 ns
```
**main**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.1 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
---------------------------------------------------------------------- -----------------------------
Headers iterator 2.59 µs/iter 386,372.1 (2.56 µs … 2.68 µs) 2.59 µs 2.68 µs 2.68 µs
```
2023-08-21 18:23:27 +05:30
Marcos Casagrande
bf9ddb7c2e
perf(ext/request): optimize Request constructor ( #20141 )
...
This PR optimizes `Request` constructor when `init` is not empty. This
path is also used by `fetch` when `options` argument is used
```js
fetch("https://deno.land ", {
method: "POST",
body: 'land'
});
```
- Removed 3 extra calls to `headerListFromHeaders`
- Avoid `Object.keys` & `headerList` clone if `init.headers` is set
- Only empty `headersList` (`.splice`) if it's not already empty.
## Benchmarks
**this patch**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.1 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
----------------------------------------------------------------------------- -----------------------------
Request without headers 1.86 µs/iter 536,440.7 (1.67 µs … 2.76 µs) 1.89 µs 2.76 µs 2.76 µs
Request with headers 1.96 µs/iter 509,440.5 (1.83 µs … 2.17 µs) 1.99 µs 2.17 µs 2.17 µs
```
**main**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.1 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
----------------------------------------------------------------------------- -----------------------------
Request without headers 1.96 µs/iter 510,201.5 (1.81 µs … 2.64 µs) 2 µs 2.64 µs 2.64 µs
Request with headers 2.03 µs/iter 493,526.6 (1.84 µs … 2.31 µs) 2.08 µs 2.31 µs 2.31 µs
```
```js
Deno.bench("Request without headers", () => {
const r = new Request("https://deno.land ", {
method: "POST",
body: '{"foo": "bar"}',
});
});
Deno.bench("Request with headers", () => {
const r = new Request("https://deno.land ", {
method: "POST",
body: '{"foo": "bar"}',
headers: {
"Content-Type": "application/json",
},
});
});
```
2023-08-21 18:23:27 +05:30
Divy Srivastava
dd3d0f6d0b
fix(node): implement TLSSocket._start ( #20120 )
...
Closes https://github.com/denoland/deno/issues/19983
Closes https://github.com/denoland/deno/issues/18303
Closes https://github.com/denoland/deno/issues/16681
Closes https://github.com/denoland/deno/issues/19978
2023-08-21 18:23:27 +05:30
Divy Srivastava
3615afa217
fix(ext/node): support dictionary option in zlib init ( #20035 )
...
Fixes https://github.com/denoland/deno/issues/19540
2023-08-21 18:23:27 +05:30
Divy Srivastava
8e060e7da8
fix(node): object keys in publicEncrypt ( #20128 )
...
Fixes https://github.com/denoland/deno/issues/19935
2023-08-21 18:23:27 +05:30
Bartek Iwańczuk
d70c43f3eb
perf(http): use Cow<[u8]> for setting header ( #20112 )
2023-08-21 18:23:27 +05:30
Bartek Iwańczuk
5515cee539
fix(node): don't print warning on process.dlopen.flags ( #20124 )
...
Closes https://github.com/denoland/deno/issues/20075
2023-08-21 18:23:27 +05:30
Marcos Casagrande
1a1283fa4d
perf(ext/http): use ServeHandlerInfo class instead of object literal ( #20122 )
...
This PR improves performance of `Deno.Serve` when providing `info`
argument by creating `ServeHandlerInfo` class instead of creating an
object literal with a getter on every request.
```js
Deno.serve((_req, info) => new Response(info.remoteAddr.transport) });
```
### Benchmarks
```
wrk -d 10s --latency http://127.0.0.1:4500
Running 10s test @ http://127.0.0.1:4500
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 42.34us 16.30us 1.66ms 95.88%
Req/Sec 118.17k 2.95k 127.38k 76.73%
Latency Distribution
50% 38.00us
75% 41.00us
90% 56.00us
99% 83.00us
2375298 requests in 10.10s, 319.40MB read
Requests/sec: 235177.04
Transfer/sec: 31.62MB
```
**main**
```
wrk -d 10s --latency http://127.0.0.1:4500
Running 10s test @ http://127.0.0.1:4500
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 78.86us 211.06us 3.58ms 96.52%
Req/Sec 105.90k 4.35k 117.41k 78.22%
Latency Distribution
50% 41.00us
75% 53.00us
90% 62.00us
99% 1.18ms
2127534 requests in 10.10s, 286.09MB read
Requests/sec: 210647.49
Transfer/sec: 28.33MB
```
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.0 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
-------------------------------------------------------------------------- -----------------------------
new ServeHandlerInfo 3.43 ns/iter 291,508,889.3 (3.07 ns … 12.21 ns) 3.42 ns 3.84 ns 3.87 ns
{} with getter 133.84 ns/iter 7,471,528.9 (92.9 ns … 458.95 ns) 132.45 ns 364.96 ns 429.43 ns
```
----
### Drawbacks:
`.remoteAddr` is now not enumerable
```
ServeHandlerInfo {}
```
vs
```
{ remoteAddr: [Getter] }
```
It'll break any code trying to iterate through `info` keys (Doubt
there's anyone doing it though)
```js
Deno.serve((req, info) => {
console.log(Object.keys(info).length === 0) // true;
return new Response("yes");
});
2023-08-21 18:23:27 +05:30
Marcos Casagrande
28142a74dd
perf(ext/headers): optimize getHeader using for loop ( #20115 )
...
This PR optimizes the `getHeader` function by replacing `.filter` and
`.map` with a `for` loop
**this patch**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.0 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
----------------------------------------------------------------- -----------------------------
Headers.get 132.2 ns/iter 7,564,093.4 (125.81 ns … 147.66 ns) 133.79 ns 144.92 ns 145.36 ns
```
**main**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.0 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
----------------------------------------------------------------- -----------------------------
Headers.get 191.48 ns/iter 5,222,523.6 (182.75 ns … 212.22 ns) 193.5 ns 205.96 ns 211.51 ns
```
```js
const headers = new Headers({
"Content-Type": "application/json",
"Date": "Thu, 10 Aug 2023 07:45:10 GMT",
"X-Deno": "Deno",
"Powered-By": "Deno",
"Content-Encoding": "gzip",
"Set-Cookie": "__Secure-ID=123; Secure; Domain=example.com",
"Content-Length": "150",
"Vary": "Accept-Encoding, Accept, X-Requested-With",
});
Deno.bench("Headers.get", () => {
const i = headers.get("x-deno");
});
```
2023-08-21 18:23:27 +05:30