← back to Watches

scripts/warmup-market-cache.js

154 lines

#!/usr/bin/env node
/**
 * Cache Warmup Script for Market Data
 * Pre-populates the server cache with real market data from Wayback Machine
 * Run this periodically to ensure fast response times
 */

const http = require('http');
const https = require('https');

// Server configuration
const SERVER_HOST = 'localhost';
const SERVER_PORT = 7600;

// All watch IDs from omega-watches.json
const WATCH_IDS = [
  'speedmaster-moonwatch',
  'speedmaster-alaska',
  'seamaster-300',
  'seamaster-ploprof',
  'seamaster-bond',
  'constellation-piepan',
  'constellation-manhattan',
  'deville-tresor',
  'deville-coaxial',
  'railmaster-original',
  'aqua-terra',
  'planet-ocean',
  'speedmaster-reduced',
  'speedmaster-mark2',
  'flightmaster'
];

// Delay between requests (ms) - be respectful to Wayback Machine
const REQUEST_DELAY = 30000; // 30 seconds

function fetchMarketData(watchId) {
  return new Promise((resolve, reject) => {
    const options = {
      hostname: SERVER_HOST,
      port: SERVER_PORT,
      path: `/api/market-data/${watchId}`,
      method: 'GET',
      timeout: 180000 // 3 minute timeout
    };

    const req = http.request(options, (res) => {
      let data = '';

      res.on('data', (chunk) => {
        data += chunk;
      });

      res.on('end', () => {
        try {
          const json = JSON.parse(data);
          resolve({
            watchId,
            success: json.success,
            isMock: json.isMock,
            source: json.source,
            price: json.marketPrice ? `$${json.marketPrice.low} - $${json.marketPrice.high}` : 'N/A'
          });
        } catch (e) {
          reject(new Error(`Failed to parse response: ${e.message}`));
        }
      });
    });

    req.on('error', (e) => {
      reject(e);
    });

    req.on('timeout', () => {
      req.destroy();
      reject(new Error('Request timeout'));
    });

    req.end();
  });
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function warmupCache() {
  console.log('╔════════════════════════════════════════════════════════════╗');
  console.log('║  MARKET DATA CACHE WARMUP                                  ║');
  console.log('╚════════════════════════════════════════════════════════════╝\n');

  console.log(`Starting cache warmup for ${WATCH_IDS.length} watches...`);
  console.log(`Request delay: ${REQUEST_DELAY / 1000} seconds\n`);

  const startTime = Date.now();
  const results = {
    success: 0,
    failed: 0,
    mock: 0,
    real: 0
  };

  for (let i = 0; i < WATCH_IDS.length; i++) {
    const watchId = WATCH_IDS[i];
    const progress = `[${i + 1}/${WATCH_IDS.length}]`;

    console.log(`${progress} Fetching ${watchId}...`);

    try {
      const result = await fetchMarketData(watchId);

      if (result.success) {
        results.success++;
        if (result.isMock) {
          results.mock++;
          console.log(`  ⚠️  Mock data: ${result.price}`);
        } else {
          results.real++;
          console.log(`  ✅ Real data: ${result.price} (${result.source})`);
        }
      } else {
        results.failed++;
        console.log(`  ❌ Failed to fetch data`);
      }
    } catch (error) {
      results.failed++;
      console.log(`  ❌ Error: ${error.message}`);
    }

    // Wait before next request (except for last one)
    if (i < WATCH_IDS.length - 1) {
      console.log(`  Waiting ${REQUEST_DELAY / 1000}s before next request...\n`);
      await sleep(REQUEST_DELAY);
    }
  }

  const elapsed = Math.round((Date.now() - startTime) / 1000);

  console.log('\n╔════════════════════════════════════════════════════════════╗');
  console.log('║  WARMUP COMPLETE                                           ║');
  console.log('╚════════════════════════════════════════════════════════════╝');
  console.log(`\nResults:`);
  console.log(`  Total:      ${WATCH_IDS.length}`);
  console.log(`  Success:    ${results.success}`);
  console.log(`  Failed:     ${results.failed}`);
  console.log(`  Real data:  ${results.real}`);
  console.log(`  Mock data:  ${results.mock}`);
  console.log(`  Time:       ${elapsed}s`);
  console.log(`\nCache is now warm! Requests will be served from cache for 1 hour.`);
}

// Run the warmup
warmupCache().catch(console.error);