odesli.js
Version:
Node.js Client to query odesli.co (song.link/album.link) API
84 lines (68 loc) ⢠2.99 kB
JavaScript
const Odesli = require('odesli.js');
const { RateLimiter } = require('odesli.js/rate-limiter');
const odesli = new Odesli();
// Test URLs
const urls = [
'https://open.spotify.com/track/4Km5HrUvYTaSUfiSGPJeQR',
'https://open.spotify.com/track/0V3wPSX9ygBnCm8psDIegu',
'https://open.spotify.com/track/3n3Ppam7vgaVa1iaRUc9Lp',
'https://open.spotify.com/track/6rqhFgbbKwnb9MLmUQDhG6',
];
// Function to test a strategy
async function testStrategy(strategy, maxRequests, windowMs) {
console.log(`\nš§ Testing ${strategy.toUpperCase()} Strategy`);
console.log(`š Config: ${maxRequests} requests per ${windowMs / 1000}s`);
console.log('ā'.repeat(50));
const limiter = new RateLimiter({
maxRequests,
windowMs,
strategy,
});
const startTime = Date.now();
// Submit all requests at once
const promises = urls.map(async (url, index) => {
const requestStart = Date.now();
console.log(`ā³ Request ${index + 1}: Waiting for slot...`);
await limiter.waitForSlot();
const waitTime = Date.now() - requestStart;
console.log(`ā
Request ${index + 1}: Got slot (waited ${waitTime}ms)`);
const song = await odesli.fetch(url);
console.log(`šµ Request ${index + 1}: ${song.title}`);
return { song, waitTime };
});
const results = await Promise.all(promises);
const totalTime = Date.now() - startTime;
console.log(`\nš Results for ${strategy}:`);
console.log(`ā±ļø Total time: ${totalTime}ms`);
console.log(
`š Average wait: ${Math.round(results.reduce((sum, r) => sum + r.waitTime, 0) / results.length)}ms`
);
console.log(`šÆ Strategy status:`, limiter.getStatus());
}
// Test all strategies
(async () => {
console.log('š Rate Limiter Strategy Comparison');
console.log('='.repeat(60));
// 1. TOKEN BUCKET - Good for burst handling
await testStrategy('token-bucket', 2, 3000);
// 2. SLIDING WINDOW - Most accurate rate limiting
await testStrategy('sliding-window', 2, 3000);
// 3. LEAKY BUCKET - Good for smoothing traffic
await testStrategy('leaky-bucket', 2, 3000);
console.log('\nš Strategy Guide:');
console.log('='.repeat(60));
console.log('šÆ TOKEN BUCKET:');
console.log(' ā
Pros: Handles bursts well, efficient memory usage');
console.log(' ā Cons: Less precise timing, can allow slight overages');
console.log(' šÆ Use when: You want to allow some burst traffic');
console.log('');
console.log('š SLIDING WINDOW:');
console.log(' ā
Pros: Most accurate, precise timing, no overages');
console.log(' ā Cons: More memory usage, slightly more complex');
console.log(' šÆ Use when: You need exact rate limiting (recommended)');
console.log('');
console.log('š§ LEAKY BUCKET:');
console.log(' ā
Pros: Smooths traffic, predictable output rate');
console.log(' ā Cons: Can delay requests, less responsive to bursts');
console.log(' šÆ Use when: You want to smooth out traffic spikes');
})();