#!/usr/bin/env node /** * Auto-Retry Usage Examples * * Shows how to integrate auto-retry into existing cron jobs */ const { executeWithRetry, executeWithNotifications } = require('../lib/auto-retry'); const https = require('https'); // ============================================================================ // Example 1: Simple API Call with Retry // ============================================================================ async function fetchStockPrice(symbol) { return new Promise((resolve, reject) => { const options = { hostname: 'query1.finance.yahoo.com', path: `/v8/finance/chart/${symbol}`, method: 'GET', timeout: 5000 }; const req = https.request(options, (res) => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => { if (res.statusCode === 200) { resolve(JSON.parse(data)); } else { const error = new Error(`HTTP ${res.statusCode}`); error.statusCode = res.statusCode; reject(error); } }); }); req.on('error', reject); req.on('timeout', () => { req.destroy(); const error = new Error('Request timeout'); error.code = 'ETIMEDOUT'; reject(error); }); req.end(); }); } async function example1_SimpleRetry() { console.log('Example 1: Simple Retry\n'); try { const result = await executeWithRetry( () => fetchStockPrice('TQQQ'), { maxRetries: 3, backoff: 'exponential', context: { task: 'fetch TQQQ price' } } ); console.log('βœ… Success:', result.success); console.log('πŸ“Š Attempts:', result.attempts); console.log('⏱️ Duration:', result.totalDuration + 'ms'); } catch (error) { console.error('❌ Failed:', error.message); } } // ============================================================================ // Example 2: With Discord Notifications // ============================================================================ async function example2_WithNotifications() { console.log('\nExample 2: With Discord Notifications\n'); const WEBHOOK = 'https://discord.com/api/webhooks/1468429341154214049/arTEGUkhIZ5bpE63AefMnyneomjwf1zDzCpzCwbdlzKpH7KgNzcMpFNX9G-DPW5HRojU'; try { const result = await executeWithNotifications( () => fetchStockPrice('TQQQ'), { maxRetries: 3, backoff: 'exponential', discordWebhook: WEBHOOK, taskName: 'TQQQ 가격 쑰회', context: { cron: 'TQQQ 15λΆ„ λͺ¨λ‹ˆν„°λ§' } } ); console.log('βœ… Success with notifications'); } catch (error) { console.error('❌ Failed with notifications'); } } // ============================================================================ // Example 3: Wrap Existing Cron Function // ============================================================================ async function originalCronFunction() { // κΈ°μ‘΄ cron 둜직 const price = await fetchStockPrice('TQQQ'); const rate = await fetchExchangeRate(); return { price: price.chart.result[0].meta.regularMarketPrice, rate }; } async function fetchExchangeRate() { // ν™˜μœ¨ API 호좜 return 1320.5; } async function example3_WrapCron() { console.log('\nExample 3: Wrap Existing Cron\n'); // Before: μž¬μ‹œλ„ μ—†μŒ // const result = await originalCronFunction(); // After: μžλ™ μž¬μ‹œλ„ μΆ”κ°€ const result = await executeWithRetry( originalCronFunction, { maxRetries: 3, backoff: 'exponential' } ); console.log('βœ… Cron result:', result.result); } // ============================================================================ // Example 4: Custom Retry Logic // ============================================================================ const { AutoRetry } = require('../lib/auto-retry'); async function example4_CustomLogic() { console.log('\nExample 4: Custom Retry Logic\n'); const retry = new AutoRetry({ maxRetries: 5, backoff: 'linear', baseDelay: 2000, // 2초 onRetry: async (attempt, error, analysis, delay) => { console.log(` πŸ”„ Retry ${attempt}:`); console.log(` Error: ${error.message}`); console.log(` Category: ${analysis.category}`); console.log(` Suggestion: ${analysis.suggestedFix}`); console.log(` Next attempt in: ${delay}ms\n`); }, onSuccess: async (attempt, result) => { if (attempt > 1) { console.log(` βœ… Recovered after ${attempt} attempts!`); } }, onFinalFailure: async (attempts, analysis) => { console.log(` ❌ Gave up after ${attempts.length} attempts`); console.log(` Suggestion: ${analysis.suggestedFix}`); // μ‚¬λžŒμ—κ²Œ μ•Œλ¦Ό (예: Discord, Email λ“±) // await notifyHuman(analysis); } }); try { const result = await retry.execute( () => fetchStockPrice('TQQQ'), { task: 'custom retry test' } ); console.log('\nβœ… Final success'); } catch (error) { console.error('\n❌ Final failure'); } } // ============================================================================ // Example 5: Integration with TQQQ Monitor // ============================================================================ async function example5_TQQQIntegration() { console.log('\nExample 5: TQQQ Monitor Integration\n'); const WEBHOOK = 'https://discord.com/api/webhooks/1468429341154214049/arTEGUkhIZ5bpE63AefMnyneomjwf1zDzCpzCwbdlzKpH7KgNzcMpFNX9G-DPW5HRojU'; // TQQQ λͺ¨λ‹ˆν„°λ§ 둜직 (κΈ°μ‘΄ μ½”λ“œμ™€ 동일) async function monitorTQQQ() { const [priceData, rate] = await Promise.all([ fetchStockPrice('TQQQ'), fetchExchangeRate() ]); const price = priceData.chart.result[0].meta.regularMarketPrice; const shares = 47; const avgPrice = 52.52; const dollarProfit = (price - avgPrice) * shares; const wonProfit = dollarProfit * rate; return { price, dollarProfit, wonProfit, rate }; } try { // μžλ™ μž¬μ‹œλ„ + Discord μ•Œλ¦Ό const result = await executeWithNotifications( monitorTQQQ, { maxRetries: 3, backoff: 'exponential', discordWebhook: WEBHOOK, taskName: 'TQQQ 15λΆ„ λͺ¨λ‹ˆν„°λ§', context: { cron: 'TQQQ 15λΆ„ λͺ¨λ‹ˆν„°λ§', schedule: '*/15 * * * *' } } ); console.log('βœ… TQQQ Monitor completed'); console.log(' Price:', result.result.price); console.log(' Dollar P/L:', result.result.dollarProfit.toFixed(2)); console.log(' Won P/L:', result.result.wonProfit.toFixed(0)); } catch (error) { console.error('❌ TQQQ Monitor failed after all retries'); } } // ============================================================================ // Run Examples // ============================================================================ async function main() { const args = process.argv.slice(2); const example = args[0] || 'all'; if (example === 'all' || example === '1') { await example1_SimpleRetry(); } if (example === 'all' || example === '2') { await example2_WithNotifications(); } if (example === 'all' || example === '3') { await example3_WrapCron(); } if (example === 'all' || example === '4') { await example4_CustomLogic(); } if (example === 'all' || example === '5') { await example5_TQQQIntegration(); } } if (require.main === module) { main().catch(console.error); } module.exports = { example1_SimpleRetry, example2_WithNotifications, example3_WrapCron, example4_CustomLogic, example5_TQQQIntegration };