File size: 7,525 Bytes
dd2b18e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
import { DuckAI } from "./duckai";

/**
 * Shared Rate Limit Tester
 *
 * This utility tests rate limits using the DuckAI class which writes to the shared store,
 * allowing cross-process monitoring to work correctly.
 */
export class SharedRateLimitTester {
  private duckAI: DuckAI;

  constructor() {
    this.duckAI = new DuckAI();
  }

  /**
   * Get current rate limit status
   */
  getCurrentStatus() {
    const status = this.duckAI.getRateLimitStatus();
    return {
      ...status,
      utilizationPercentage:
        (status.requestsInCurrentWindow / status.maxRequestsPerMinute) * 100,
      timeUntilWindowResetMinutes: Math.ceil(
        status.timeUntilWindowReset / 60000
      ),
      recommendedWaitTimeSeconds: Math.ceil(status.recommendedWaitTime / 1000),
    };
  }

  /**
   * Print current rate limit status to console
   */
  printStatus() {
    const status = this.getCurrentStatus();

    console.log("\nπŸ” DuckAI Rate Limit Status (Shared Tester):");
    console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    console.log(
      `πŸ“Š Requests in current window: ${status.requestsInCurrentWindow}/${status.maxRequestsPerMinute}`
    );
    console.log(`πŸ“ˆ Utilization: ${status.utilizationPercentage.toFixed(1)}%`);
    console.log(
      `⏰ Window resets in: ${status.timeUntilWindowResetMinutes} minutes`
    );
    console.log(
      `🚦 Currently limited: ${status.isCurrentlyLimited ? "❌ Yes" : "βœ… No"}`
    );

    if (status.recommendedWaitTimeSeconds > 0) {
      console.log(
        `⏳ Recommended wait: ${status.recommendedWaitTimeSeconds} seconds`
      );
    }

    // Visual progress bar
    const barLength = 20;
    const filledLength = Math.round(
      (status.utilizationPercentage / 100) * barLength
    );
    const bar = "β–ˆ".repeat(filledLength) + "β–‘".repeat(barLength - filledLength);
    console.log(
      `πŸ“Š Usage: [${bar}] ${status.utilizationPercentage.toFixed(1)}%`
    );
    console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
  }

  /**
   * Test rate limits by making a series of requests using DuckAI (writes to shared store)
   */
  async testRateLimits(
    numberOfRequests: number = 5,
    delayBetweenRequests: number = 1000
  ) {
    console.log(
      `πŸ§ͺ Testing rate limits with ${numberOfRequests} requests (${delayBetweenRequests}ms delay)...`
    );
    console.log(
      "πŸ“‘ Using DuckAI class - data will be shared across processes!"
    );

    for (let i = 1; i <= numberOfRequests; i++) {
      console.log(`\nπŸ“€ Making request ${i}/${numberOfRequests}...`);

      try {
        const startTime = Date.now();

        const response = await this.duckAI.chat({
          model: "gpt-4o-mini",
          messages: [{ role: "user", content: `Shared test request ${i}` }],
        });

        const endTime = Date.now();
        const responseTime = endTime - startTime;

        console.log(`βœ… Request ${i} successful (${responseTime}ms)`);
        this.printStatus();

        if (i < numberOfRequests) {
          console.log(
            `⏳ Waiting ${delayBetweenRequests}ms before next request...`
          );
          await new Promise((resolve) =>
            setTimeout(resolve, delayBetweenRequests)
          );
        }
      } catch (error) {
        const errorMessage =
          error instanceof Error ? error.message : String(error);
        console.log(`❌ Request ${i} failed:`, errorMessage);
        this.printStatus();

        // If rate limited, wait longer
        if (errorMessage.includes("Rate limited")) {
          const waitTime =
            this.getCurrentStatus().recommendedWaitTimeSeconds * 1000;
          console.log(`⏳ Rate limited! Waiting ${waitTime}ms...`);
          await new Promise((resolve) => setTimeout(resolve, waitTime));
        }
      }
    }

    console.log("\n🏁 Shared rate limit test completed!");
    console.log(
      "πŸ“‘ Data has been written to shared store for cross-process monitoring!"
    );
  }

  /**
   * Get recommendations for optimal usage
   */
  getRecommendations() {
    const status = this.getCurrentStatus();
    const recommendations: string[] = [];

    if (status.utilizationPercentage > 80) {
      recommendations.push(
        "⚠️  High utilization detected. Consider implementing request queuing."
      );
    }

    if (status.recommendedWaitTimeSeconds > 0) {
      recommendations.push(
        `⏳ Wait ${status.recommendedWaitTimeSeconds}s before next request.`
      );
    }

    if (status.isCurrentlyLimited) {
      recommendations.push(
        "🚫 Currently rate limited. Wait for window reset or implement exponential backoff."
      );
    }

    if (status.utilizationPercentage < 50) {
      recommendations.push(
        "βœ… Good utilization level. You can safely increase request frequency."
      );
    }

    recommendations.push(
      "πŸ’‘ Consider implementing request batching for better efficiency."
    );
    recommendations.push("πŸ”„ Use exponential backoff for retry logic.");
    recommendations.push("πŸ“Š Monitor rate limits continuously in production.");
    recommendations.push(
      "πŸ“‘ Use shared monitoring for cross-process visibility."
    );

    return recommendations;
  }

  /**
   * Print recommendations
   */
  printRecommendations() {
    const recommendations = this.getRecommendations();

    console.log("\nπŸ’‘ Rate Limit Recommendations:");
    console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    recommendations.forEach((rec) => console.log(rec));
    console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
  }
}

// CLI usage
if (require.main === module) {
  const tester = new SharedRateLimitTester();

  // Parse command line arguments
  const args = process.argv.slice(2);
  const command = args[0];

  switch (command) {
    case "status":
      tester.printStatus();
      tester.printRecommendations();
      break;

    case "test":
      const requests = parseInt(args[1]) || 5;
      const delay = parseInt(args[2]) || 1000;
      tester.testRateLimits(requests, delay).then(() => {
        tester.printRecommendations();
        process.exit(0);
      });
      break;

    default:
      console.log("πŸ” DuckAI Shared Rate Limit Tester");
      console.log("πŸ“‘ Uses DuckAI class - data is shared across processes!");
      console.log("");
      console.log("Usage:");
      console.log(
        "  bun run src/shared-rate-limit-tester.ts status                    # Show current status"
      );
      console.log(
        "  bun run src/shared-rate-limit-tester.ts test [requests] [delay]  # Test rate limits (shared)"
      );
      console.log("");
      console.log("Examples:");
      console.log("  bun run src/shared-rate-limit-tester.ts status");
      console.log("  bun run src/shared-rate-limit-tester.ts test 10 2000");
      console.log("");
      console.log("πŸ’‘ For cross-process monitoring, run this in one terminal:");
      console.log("  bun run src/shared-rate-limit-tester.ts test 20 3000");
      console.log("");
      console.log("And this in another terminal:");
      console.log("  bun run src/shared-rate-limit-monitor.ts monitor 2");
      break;
  }
}