@nxtedition/nxt-undici 7.3.19 → 7.3.20
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/lib/interceptor/dns.js +26 -26
- package/package.json +1 -1
package/lib/interceptor/dns.js
CHANGED
|
@@ -52,7 +52,6 @@ export default () => (dispatch) => {
|
|
|
52
52
|
pending: 0,
|
|
53
53
|
errored: 0,
|
|
54
54
|
counter: 0,
|
|
55
|
-
timeout: 0,
|
|
56
55
|
}
|
|
57
56
|
})
|
|
58
57
|
|
|
@@ -68,35 +67,31 @@ export default () => (dispatch) => {
|
|
|
68
67
|
}
|
|
69
68
|
|
|
70
69
|
return async (opts, handler) => {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
try {
|
|
71
|
+
if (!opts.dns || !opts.origin) {
|
|
72
|
+
return dispatch(opts, handler)
|
|
73
|
+
}
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
const ttl = opts.dns.ttl ?? 2e3
|
|
76
|
+
const url = new URL(opts.path ?? '', opts.origin)
|
|
77
|
+
const balance = opts.dns.balance
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
const { host, hostname, pathname } = url
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
if (net.isIP(hostname)) {
|
|
82
|
+
return dispatch(opts, handler)
|
|
83
|
+
}
|
|
84
84
|
|
|
85
|
-
try {
|
|
86
85
|
const now = getFastNow()
|
|
87
86
|
|
|
88
87
|
let records = cache.get(hostname)
|
|
89
88
|
|
|
90
89
|
if (records == null || records.every((x) => x.expires < now)) {
|
|
91
90
|
const [err, val] = await resolve(hostname, { ttl })
|
|
92
|
-
|
|
93
91
|
if (err) {
|
|
94
92
|
throw err
|
|
95
93
|
}
|
|
96
|
-
|
|
97
94
|
records = val
|
|
98
|
-
} else if (records.some((x) => x.expires < now + 1e3)) {
|
|
99
|
-
resolve(hostname, { ttl })
|
|
100
95
|
}
|
|
101
96
|
|
|
102
97
|
let record
|
|
@@ -108,7 +103,7 @@ export default () => (dispatch) => {
|
|
|
108
103
|
|
|
109
104
|
for (let i = 0; i < records.length; i++) {
|
|
110
105
|
const idx = (hash + i) % records.length
|
|
111
|
-
if (records[idx].expires >= now
|
|
106
|
+
if (records[idx].expires >= now) {
|
|
112
107
|
record = records[idx]
|
|
113
108
|
break
|
|
114
109
|
}
|
|
@@ -116,13 +111,14 @@ export default () => (dispatch) => {
|
|
|
116
111
|
}
|
|
117
112
|
|
|
118
113
|
if (record == null) {
|
|
119
|
-
|
|
114
|
+
// toSorted — balance:'hash' relies on the cached array's index order.
|
|
115
|
+
const sorted = records.toSorted(
|
|
120
116
|
(a, b) => a.errored - b.errored || a.pending - b.pending || a.counter - b.counter,
|
|
121
117
|
)
|
|
122
118
|
|
|
123
|
-
for (let i = 0; i <
|
|
124
|
-
if (
|
|
125
|
-
record =
|
|
119
|
+
for (let i = 0; i < sorted.length; i++) {
|
|
120
|
+
if (sorted[i].expires >= now) {
|
|
121
|
+
record = sorted[i]
|
|
126
122
|
break
|
|
127
123
|
}
|
|
128
124
|
}
|
|
@@ -135,7 +131,15 @@ export default () => (dispatch) => {
|
|
|
135
131
|
})
|
|
136
132
|
}
|
|
137
133
|
|
|
138
|
-
|
|
134
|
+
// Pre-emptive refresh when any record is past half its TTL — the
|
|
135
|
+
// in-flight request still uses the already-selected `record`; the
|
|
136
|
+
// refreshed records land in cache for the next request, smoothing
|
|
137
|
+
// out DNS lookup latency. `resolve()` dedupes via `promises`.
|
|
138
|
+
if (records.some((x) => x.expires < now + ttl / 2)) {
|
|
139
|
+
resolve(hostname, { ttl })
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
url.hostname = net.isIPv6(record.address) ? `[${record.address}]` : record.address
|
|
139
143
|
|
|
140
144
|
record.counter++
|
|
141
145
|
record.pending++
|
|
@@ -150,10 +154,6 @@ export default () => (dispatch) => {
|
|
|
150
154
|
} else if (statusCode != null && statusCode >= 500) {
|
|
151
155
|
record.errored++
|
|
152
156
|
}
|
|
153
|
-
|
|
154
|
-
if (err != null || statusCode >= 500) {
|
|
155
|
-
record.timeout = getFastNow() + 10e3
|
|
156
|
-
}
|
|
157
157
|
}),
|
|
158
158
|
)
|
|
159
159
|
} catch (err) {
|