com.jimuwd.xian.registry-proxy 1.0.96 → 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,33 +8,9 @@ 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
- const limiter = new ConcurrencyLimiter(10);
13
+ const limiter = new ConcurrencyLimiter(Infinity);
38
14
  function removeEndingSlashAndForceStartingSlash(str) {
39
15
  if (!str)
40
16
  return '/';
@@ -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&param=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,9 @@
1
+ export default class ConcurrencyLimiter {
2
+ readonly maxConcurrency: number;
3
+ private current;
4
+ private queue;
5
+ constructor(maxConcurrency: number);
6
+ acquire(): Promise<void>;
7
+ release(): void;
8
+ run<T>(task: () => Promise<T>): Promise<T>;
9
+ }
@@ -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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.jimuwd.xian.registry-proxy",
3
- "version": "1.0.96",
3
+ "version": "1.0.98",
4
4
  "description": "A lightweight npm registry proxy with fallback support",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",