GeminiBot commited on
Commit
5a97b06
·
1 Parent(s): 5ceef9b

Implement concurrency queue (max 5) to protect IP from DDG burst bans

Browse files
Files changed (1) hide show
  1. src/duckai.ts +33 -4
src/duckai.ts CHANGED
@@ -4,9 +4,36 @@ import { Buffer } from "node:buffer";
4
  import UserAgent from "user-agents";
5
 
6
  let activeRequests = 0;
 
 
7
 
8
  export class DuckAI {
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  private async solveChallenge(vqdHash: string, reqId: string): Promise<string> {
11
  const start = Date.now();
12
  const memBefore = process.memoryUsage().heapUsed / 1024 / 1024;
@@ -79,10 +106,12 @@ export class DuckAI {
79
 
80
  async chat(request: any): Promise<string> {
81
  const reqId = Math.random().toString(36).substring(7).toUpperCase();
82
- activeRequests++;
83
- const startTime = Date.now();
84
 
85
- console.log(`[${reqId}] [Chat] NEW REQUEST. Parallel active: ${activeRequests}`);
 
 
 
 
86
 
87
  // Добавляем Jitter (случайную задержку 0-500мс), чтобы не долбить DDG пачкой
88
  await new Promise(r => setTimeout(resolve => r(resolve), Math.random() * 500));
@@ -156,7 +185,7 @@ export class DuckAI {
156
  console.error(`[${reqId}] [Chat] FAILED: ${error.message}`);
157
  throw error;
158
  } finally {
159
- activeRequests--;
160
  }
161
  }
162
 
 
4
  import UserAgent from "user-agents";
5
 
6
  let activeRequests = 0;
7
+ const MAX_CONCURRENT_CHATS = 5; // Максимум 5 одновременных запросов к DDG
8
+ const requestQueue: (() => void)[] = [];
9
 
10
  export class DuckAI {
11
 
12
+ // Метод для ожидания своей очереди
13
+ private async acquireSlot(reqId: string): Promise<void> {
14
+ if (activeRequests < MAX_CONCURRENT_CHATS) {
15
+ activeRequests++;
16
+ return;
17
+ }
18
+
19
+ console.log(`[${reqId}] [Queue] Space busy (${activeRequests} active). Waiting for slot...`);
20
+ return new Promise((resolve) => {
21
+ requestQueue.push(() => {
22
+ activeRequests++;
23
+ resolve();
24
+ });
25
+ });
26
+ }
27
+
28
+ // Освобождение слота
29
+ private releaseSlot() {
30
+ activeRequests--;
31
+ if (requestQueue.length > 0) {
32
+ const next = requestQueue.shift();
33
+ if (next) next();
34
+ }
35
+ }
36
+
37
  private async solveChallenge(vqdHash: string, reqId: string): Promise<string> {
38
  const start = Date.now();
39
  const memBefore = process.memoryUsage().heapUsed / 1024 / 1024;
 
106
 
107
  async chat(request: any): Promise<string> {
108
  const reqId = Math.random().toString(36).substring(7).toUpperCase();
 
 
109
 
110
+ // Ждем свободный слот (максимум 5 параллельно)
111
+ await this.acquireSlot(reqId);
112
+
113
+ const startTime = Date.now();
114
+ console.log(`[${reqId}] [Chat] STARTING (Active: ${activeRequests}, Queued: ${requestQueue.length})`);
115
 
116
  // Добавляем Jitter (случайную задержку 0-500мс), чтобы не долбить DDG пачкой
117
  await new Promise(r => setTimeout(resolve => r(resolve), Math.random() * 500));
 
185
  console.error(`[${reqId}] [Chat] FAILED: ${error.message}`);
186
  throw error;
187
  } finally {
188
+ this.releaseSlot();
189
  }
190
  }
191