| import { DuckAI } from "./duckai"; |
|
|
| |
| |
| |
| |
| |
| |
| export class SharedRateLimitTester { |
| private duckAI: DuckAI; |
|
|
| constructor() { |
| this.duckAI = new DuckAI(); |
| } |
|
|
| |
| |
| |
| 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), |
| }; |
| } |
|
|
| |
| |
| |
| 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` |
| ); |
| } |
|
|
| |
| 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"); |
| } |
|
|
| |
| |
| |
| 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 (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!" |
| ); |
| } |
|
|
| |
| |
| |
| 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; |
| } |
|
|
| |
| |
| |
| printRecommendations() { |
| const recommendations = this.getRecommendations(); |
|
|
| console.log("\nπ‘ Rate Limit Recommendations:"); |
| console.log("ββββββββββββββββββββββββββββββββββββββββ"); |
| recommendations.forEach((rec) => console.log(rec)); |
| console.log("ββββββββββββββββββββββββββββββββββββββββ\n"); |
| } |
| } |
|
|
| |
| if (require.main === module) { |
| const tester = new SharedRateLimitTester(); |
|
|
| |
| 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; |
| } |
| } |
|
|