undici 7.0.0-alpha.5 → 7.0.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -34
- package/lib/cache/memory-cache-store.js +1 -2
- package/lib/handler/cache-handler.js +2 -3
- package/lib/interceptor/cache.js +3 -3
- package/lib/interceptor/dns.js +8 -2
- package/lib/util/timers.js +1 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,41 +22,26 @@ npm i undici
|
|
|
22
22
|
## Benchmarks
|
|
23
23
|
|
|
24
24
|
The benchmark is a simple getting data [example](https://github.com/nodejs/undici/blob/main/benchmarks/benchmark.js) using a
|
|
25
|
-
50 TCP connections with a pipelining depth of 10 running on Node
|
|
26
|
-
|
|
27
|
-
| _Tests_ | _Samples_ | _Result_ | _Tolerance_ | _Difference with slowest_ |
|
|
28
|
-
| :-----------------: | :-------: | :--------------: | :---------: | :-----------------------: |
|
|
29
|
-
| undici - fetch | 30 | 3704.43 req/sec | ± 2.95 % | - |
|
|
30
|
-
| http - no keepalive | 20 | 4275.30 req/sec | ± 2.60 % | + 15.41 % |
|
|
31
|
-
| node-fetch | 10 | 4759.42 req/sec | ± 0.87 % | + 28.48 % |
|
|
32
|
-
| request | 40 | 4803.37 req/sec | ± 2.77 % | + 29.67 % |
|
|
33
|
-
| axios | 45 | 4951.97 req/sec | ± 2.88 % | + 33.68 % |
|
|
34
|
-
| got | 10 | 5969.67 req/sec | ± 2.64 % | + 61.15 % |
|
|
35
|
-
| superagent | 10 | 9471.48 req/sec | ± 1.50 % | + 155.68 % |
|
|
36
|
-
| http - keepalive | 25 | 10327.49 req/sec | ± 2.95 % | + 178.79 % |
|
|
37
|
-
| undici - pipeline | 10 | 15053.41 req/sec | ± 1.63 % | + 306.36 % |
|
|
38
|
-
| undici - request | 10 | 19264.24 req/sec | ± 1.74 % | + 420.03 % |
|
|
39
|
-
| undici - stream | 15 | 20317.29 req/sec | ± 2.13 % | + 448.46 % |
|
|
40
|
-
| undici - dispatch | 10 | 24883.28 req/sec | ± 1.54 % | + 571.72 % |
|
|
41
|
-
|
|
42
|
-
The benchmark is a simple sending data [example](https://github.com/nodejs/undici/blob/main/benchmarks/post-benchmark.js) using a
|
|
43
|
-
50 TCP connections with a pipelining depth of 10 running on Node 20.10.0.
|
|
44
|
-
|
|
45
|
-
| _Tests_ | _Samples_ | _Result_ | _Tolerance_ | _Difference with slowest_ |
|
|
46
|
-
| :-----------------: | :-------: | :-------------: | :---------: | :-----------------------: |
|
|
47
|
-
| undici - fetch | 20 | 1968.42 req/sec | ± 2.63 % | - |
|
|
48
|
-
| http - no keepalive | 25 | 2330.30 req/sec | ± 2.99 % | + 18.38 % |
|
|
49
|
-
| node-fetch | 20 | 2485.36 req/sec | ± 2.70 % | + 26.26 % |
|
|
50
|
-
| got | 15 | 2787.68 req/sec | ± 2.56 % | + 41.62 % |
|
|
51
|
-
| request | 30 | 2805.10 req/sec | ± 2.59 % | + 42.50 % |
|
|
52
|
-
| axios | 10 | 3040.45 req/sec | ± 1.72 % | + 54.46 % |
|
|
53
|
-
| superagent | 20 | 3358.29 req/sec | ± 2.51 % | + 70.61 % |
|
|
54
|
-
| http - keepalive | 20 | 3477.94 req/sec | ± 2.51 % | + 76.69 % |
|
|
55
|
-
| undici - pipeline | 25 | 3812.61 req/sec | ± 2.80 % | + 93.69 % |
|
|
56
|
-
| undici - request | 10 | 6067.00 req/sec | ± 0.94 % | + 208.22 % |
|
|
57
|
-
| undici - stream | 10 | 6391.61 req/sec | ± 1.98 % | + 224.71 % |
|
|
58
|
-
| undici - dispatch | 10 | 6397.00 req/sec | ± 1.48 % | + 224.98 % |
|
|
25
|
+
50 TCP connections with a pipelining depth of 10 running on Node 22.11.0.
|
|
59
26
|
|
|
27
|
+
```
|
|
28
|
+
┌────────────────────────┬─────────┬────────────────────┬────────────┬─────────────────────────┐
|
|
29
|
+
│ Tests │ Samples │ Result │ Tolerance │ Difference with slowest │
|
|
30
|
+
├────────────────────────┼─────────┼────────────────────┼────────────┼─────────────────────────┤
|
|
31
|
+
│ 'axios' │ 15 │ '5708.26 req/sec' │ '± 2.91 %' │ '-' │
|
|
32
|
+
│ 'http - no keepalive' │ 10 │ '5809.80 req/sec' │ '± 2.30 %' │ '+ 1.78 %' │
|
|
33
|
+
│ 'request' │ 30 │ '5828.80 req/sec' │ '± 2.91 %' │ '+ 2.11 %' │
|
|
34
|
+
│ 'undici - fetch' │ 40 │ '5903.78 req/sec' │ '± 2.87 %' │ '+ 3.43 %' │
|
|
35
|
+
│ 'node-fetch' │ 10 │ '5945.40 req/sec' │ '± 2.13 %' │ '+ 4.15 %' │
|
|
36
|
+
│ 'got' │ 35 │ '6511.45 req/sec' │ '± 2.84 %' │ '+ 14.07 %' │
|
|
37
|
+
│ 'http - keepalive' │ 65 │ '9193.24 req/sec' │ '± 2.92 %' │ '+ 61.05 %' │
|
|
38
|
+
│ 'superagent' │ 35 │ '9339.43 req/sec' │ '± 2.95 %' │ '+ 63.61 %' │
|
|
39
|
+
│ 'undici - pipeline' │ 50 │ '13364.62 req/sec' │ '± 2.93 %' │ '+ 134.13 %' │
|
|
40
|
+
│ 'undici - stream' │ 95 │ '18245.36 req/sec' │ '± 2.99 %' │ '+ 219.63 %' │
|
|
41
|
+
│ 'undici - request' │ 50 │ '18340.17 req/sec' │ '± 2.84 %' │ '+ 221.29 %' │
|
|
42
|
+
│ 'undici - dispatch' │ 40 │ '22234.42 req/sec' │ '± 2.94 %' │ '+ 289.51 %' │
|
|
43
|
+
└────────────────────────┴─────────┴────────────────────┴────────────┴─────────────────────────┘
|
|
44
|
+
```
|
|
60
45
|
|
|
61
46
|
## Quick Start
|
|
62
47
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { Writable } = require('node:stream')
|
|
4
|
-
const { nowAbsolute } = require('../util/timers.js')
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* @typedef {import('../../types/cache-interceptor.d.ts').default.CacheKey} CacheKey
|
|
@@ -77,7 +76,7 @@ class MemoryCacheStore {
|
|
|
77
76
|
|
|
78
77
|
const topLevelKey = `${key.origin}:${key.path}`
|
|
79
78
|
|
|
80
|
-
const now =
|
|
79
|
+
const now = Date.now()
|
|
81
80
|
const entry = this.#entries.get(topLevelKey)?.find((entry) => (
|
|
82
81
|
entry.deleteAt > now &&
|
|
83
82
|
entry.method === key.method &&
|
|
@@ -7,7 +7,6 @@ const {
|
|
|
7
7
|
parseVaryHeader,
|
|
8
8
|
isEtagUsable
|
|
9
9
|
} = require('../util/cache')
|
|
10
|
-
const { nowAbsolute } = require('../util/timers.js')
|
|
11
10
|
|
|
12
11
|
function noop () {}
|
|
13
12
|
|
|
@@ -123,7 +122,7 @@ class CacheHandler extends DecoratorHandler {
|
|
|
123
122
|
return downstreamOnHeaders()
|
|
124
123
|
}
|
|
125
124
|
|
|
126
|
-
const now =
|
|
125
|
+
const now = Date.now()
|
|
127
126
|
const staleAt = determineStaleAt(now, headers, cacheControlDirectives)
|
|
128
127
|
if (staleAt) {
|
|
129
128
|
const varyDirectives = this.#cacheKey.headers && headers.vary
|
|
@@ -311,7 +310,7 @@ function determineStaleAt (now, headers, cacheControlDirectives) {
|
|
|
311
310
|
// https://www.rfc-editor.org/rfc/rfc9111.html#section-5.3
|
|
312
311
|
const expiresDate = new Date(headers.expire)
|
|
313
312
|
if (expiresDate instanceof Date && !isNaN(expiresDate)) {
|
|
314
|
-
return now + (
|
|
313
|
+
return now + (Date.now() - expiresDate.getTime())
|
|
315
314
|
}
|
|
316
315
|
}
|
|
317
316
|
|
package/lib/interceptor/cache.js
CHANGED
|
@@ -7,7 +7,6 @@ const CacheHandler = require('../handler/cache-handler')
|
|
|
7
7
|
const MemoryCacheStore = require('../cache/memory-cache-store')
|
|
8
8
|
const CacheRevalidationHandler = require('../handler/cache-revalidation-handler')
|
|
9
9
|
const { assertCacheStore, assertCacheMethods, makeCacheKey, parseCacheControlHeader } = require('../util/cache.js')
|
|
10
|
-
const { nowAbsolute } = require('../util/timers.js')
|
|
11
10
|
|
|
12
11
|
const AGE_HEADER = Buffer.from('age')
|
|
13
12
|
|
|
@@ -56,7 +55,7 @@ function needsRevalidation (result, age, cacheControlDirectives) {
|
|
|
56
55
|
return true
|
|
57
56
|
}
|
|
58
57
|
|
|
59
|
-
const now =
|
|
58
|
+
const now = Date.now()
|
|
60
59
|
if (now > result.staleAt) {
|
|
61
60
|
// Response is stale
|
|
62
61
|
if (cacheControlDirectives?.['max-stale']) {
|
|
@@ -186,6 +185,7 @@ module.exports = (opts = {}) => {
|
|
|
186
185
|
if (typeof handler.onHeaders === 'function') {
|
|
187
186
|
// Add the age header
|
|
188
187
|
// https://www.rfc-editor.org/rfc/rfc9111.html#name-age
|
|
188
|
+
const age = Math.round((Date.now() - result.cachedAt) / 1000)
|
|
189
189
|
|
|
190
190
|
// TODO (fix): What if rawHeaders already contains age header?
|
|
191
191
|
rawHeaders = [...rawHeaders, AGE_HEADER, Buffer.from(`${age}`)]
|
|
@@ -216,7 +216,7 @@ module.exports = (opts = {}) => {
|
|
|
216
216
|
throw new Error('stream is undefined but method isn\'t HEAD')
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
const age = Math.round((
|
|
219
|
+
const age = Math.round((Date.now() - result.cachedAt) / 1000)
|
|
220
220
|
if (requestCacheControl?.['max-age'] && age >= requestCacheControl['max-age']) {
|
|
221
221
|
// Response is considered expired for this specific request
|
|
222
222
|
// https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.1.1
|
package/lib/interceptor/dns.js
CHANGED
|
@@ -352,9 +352,15 @@ module.exports = interceptorOpts => {
|
|
|
352
352
|
return handler.onError(err)
|
|
353
353
|
}
|
|
354
354
|
|
|
355
|
-
|
|
355
|
+
let dispatchOpts = null
|
|
356
|
+
dispatchOpts = {
|
|
356
357
|
...origDispatchOpts,
|
|
357
|
-
|
|
358
|
+
servername: origin.hostname, // For SNI on TLS
|
|
359
|
+
origin: newOrigin,
|
|
360
|
+
headers: {
|
|
361
|
+
host: origin.hostname,
|
|
362
|
+
...origDispatchOpts.headers
|
|
363
|
+
}
|
|
358
364
|
}
|
|
359
365
|
|
|
360
366
|
dispatch(
|
package/lib/util/timers.js
CHANGED
|
@@ -21,13 +21,6 @@
|
|
|
21
21
|
*/
|
|
22
22
|
let fastNow = 0
|
|
23
23
|
|
|
24
|
-
/**
|
|
25
|
-
* The fastNowAbsolute variable contains the rough result of Date.now()
|
|
26
|
-
*
|
|
27
|
-
* @type {number}
|
|
28
|
-
*/
|
|
29
|
-
let fastNowAbsolute = Date.now()
|
|
30
|
-
|
|
31
24
|
/**
|
|
32
25
|
* RESOLUTION_MS represents the target resolution time in milliseconds.
|
|
33
26
|
*
|
|
@@ -129,8 +122,6 @@ function onTick () {
|
|
|
129
122
|
*/
|
|
130
123
|
fastNow += TICK_MS
|
|
131
124
|
|
|
132
|
-
fastNowAbsolute = Date.now()
|
|
133
|
-
|
|
134
125
|
/**
|
|
135
126
|
* The `idx` variable is used to iterate over the `fastTimers` array.
|
|
136
127
|
* Expired timers are removed by replacing them with the last element in the array.
|
|
@@ -399,9 +390,6 @@ module.exports = {
|
|
|
399
390
|
now () {
|
|
400
391
|
return fastNow
|
|
401
392
|
},
|
|
402
|
-
nowAbsolute () {
|
|
403
|
-
return fastNowAbsolute
|
|
404
|
-
},
|
|
405
393
|
/**
|
|
406
394
|
* Trigger the onTick function to process the fastTimers array.
|
|
407
395
|
* Exported for testing purposes only.
|
|
@@ -431,11 +419,5 @@ module.exports = {
|
|
|
431
419
|
* Marking as deprecated to discourage any use outside of testing.
|
|
432
420
|
* @deprecated
|
|
433
421
|
*/
|
|
434
|
-
kFastTimer
|
|
435
|
-
/**
|
|
436
|
-
* Exporting for testing purposes only.
|
|
437
|
-
* Marking as deprecated to discourage any use outside of testing.
|
|
438
|
-
* @deprecated
|
|
439
|
-
*/
|
|
440
|
-
RESOLUTION_MS
|
|
422
|
+
kFastTimer
|
|
441
423
|
}
|