com.jimuwd.xian.registry-proxy 1.0.97 → 1.0.98
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/dist/index.js
CHANGED
|
@@ -8,32 +8,8 @@ import { homedir } from 'os';
|
|
|
8
8
|
import { join, resolve } from 'path';
|
|
9
9
|
import { URL } from 'url';
|
|
10
10
|
import logger from "./utils/logger.js";
|
|
11
|
+
import ConcurrencyLimiter from "./utils/ConcurrencyLimiter.js";
|
|
11
12
|
const { readFile, writeFile } = fsPromises;
|
|
12
|
-
class ConcurrencyLimiter {
|
|
13
|
-
maxConcurrency;
|
|
14
|
-
current = 0;
|
|
15
|
-
queue = [];
|
|
16
|
-
constructor(maxConcurrency) {
|
|
17
|
-
this.maxConcurrency = maxConcurrency;
|
|
18
|
-
}
|
|
19
|
-
async acquire() {
|
|
20
|
-
if (this.current < this.maxConcurrency) {
|
|
21
|
-
this.current++;
|
|
22
|
-
return Promise.resolve();
|
|
23
|
-
}
|
|
24
|
-
return new Promise((resolve) => {
|
|
25
|
-
this.queue.push(resolve);
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
release() {
|
|
29
|
-
this.current--;
|
|
30
|
-
const next = this.queue.shift();
|
|
31
|
-
if (next) {
|
|
32
|
-
this.current++;
|
|
33
|
-
next();
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
13
|
const limiter = new ConcurrencyLimiter(Infinity);
|
|
38
14
|
function removeEndingSlashAndForceStartingSlash(str) {
|
|
39
15
|
if (!str)
|
|
@@ -309,7 +285,8 @@ export async function startProxyServer(proxyConfigPath, localYarnConfigPath, glo
|
|
|
309
285
|
const downstreamRequestedHttpMethod = reqFromDownstreamClient.method; // "GET", "POST", etc.
|
|
310
286
|
const downstreamRequestedHost = reqFromDownstreamClient.headers.host; // "example.com:8080"
|
|
311
287
|
const downstreamRequestedFullPath = reqFromDownstreamClient.url; // "/some/path?param=1¶m=2"
|
|
312
|
-
logger.info(`Received downstream request ${downstreamUserAgent} ${downstreamIp} ${downstreamRequestedHttpMethod} ${downstreamRequestedHost} ${downstreamRequestedFullPath}
|
|
288
|
+
logger.info(`Received downstream request from '${downstreamUserAgent}' ${downstreamIp} ${downstreamRequestedHttpMethod} ${downstreamRequestedHost} ${downstreamRequestedFullPath}
|
|
289
|
+
Proxy server request handler rate limit is ${limiter.maxConcurrency}`);
|
|
313
290
|
if (!downstreamRequestedFullPath || !downstreamRequestedHost) {
|
|
314
291
|
logger.warn(`400 Invalid Request, downstream ${downstreamUserAgent} req.url is absent or downstream.headers.host is absent.`);
|
|
315
292
|
resToDownstreamClient.writeHead(400).end('Invalid Request');
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export default class ConcurrencyLimiter {
|
|
2
|
+
maxConcurrency;
|
|
3
|
+
current = 0;
|
|
4
|
+
queue = [];
|
|
5
|
+
constructor(maxConcurrency) {
|
|
6
|
+
if (maxConcurrency <= 0) {
|
|
7
|
+
throw new Error("maxConcurrency must be positive");
|
|
8
|
+
}
|
|
9
|
+
this.maxConcurrency = maxConcurrency;
|
|
10
|
+
}
|
|
11
|
+
async acquire() {
|
|
12
|
+
if (this.current < this.maxConcurrency) {
|
|
13
|
+
this.current++;
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
return new Promise((resolve) => {
|
|
17
|
+
this.queue.push(resolve);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
release() {
|
|
21
|
+
if (this.current <= 0) {
|
|
22
|
+
throw new Error("release() called without acquire()");
|
|
23
|
+
}
|
|
24
|
+
this.current--;
|
|
25
|
+
const next = this.queue.shift();
|
|
26
|
+
if (next) {
|
|
27
|
+
// 异步执行,避免递归调用栈溢出
|
|
28
|
+
Promise.resolve().then(() => {
|
|
29
|
+
this.current++;
|
|
30
|
+
next();
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async run(task) {
|
|
35
|
+
await this.acquire();
|
|
36
|
+
try {
|
|
37
|
+
return await task();
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
this.release();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|