Examples/Timeout Configuration

Timeout Configuration

Demonstrates the flexible timeout configuration system. You can set timeouts for worker startup, server connection, a default message timeout, and per-message-type timeouts for fine-grained control over long-running operations.

Timeout Configuration

Demonstrates the flexible timeout configuration system. You can set timeouts for worker startup, server connection, a default message timeout, and per-message-type timeouts for fine-grained control over long-running operations.

Additional Files

messages.ts
/**
 * Shared message definitions for the timeout configuration example
 */

import { DefineMessages } from 'isolated-workers';

/**
 * Message types demonstrating different timeout requirements
 */
export type Messages = DefineMessages<{
  // Fast operation - should complete quickly
  quickPing: {
    payload: { timestamp: number };
    result: { latency: number };
  };
  // Simulated slow operation
  slowProcess: {
    payload: { durationMs: number };
    result: { completed: boolean; actualDuration: number };
  };
}>;
host.ts
/**
 * Timeout Configuration Example - Host (Client) Side
 *
 * This example demonstrates the flexible timeout configuration:
 * - WORKER_STARTUP: Time to wait for worker to start
 * - SERVER_CONNECT: Time for server to wait for host connection
 * - WORKER_MESSAGE: Default timeout for all messages
 * - Per-message-type timeouts for fine-grained control
 */

import { createWorker, type TimeoutConfig } from 'isolated-workers';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import type { Messages } from './messages.js';

const __dirname = dirname(fileURLToPath(import.meta.url));

async function main() {
  console.log('Starting timeout configuration example...\n');

  // Define timeout configuration
  const timeoutConfig: TimeoutConfig<Messages> = {
    // Worker lifecycle timeouts
    WORKER_STARTUP: 5000, // 5 seconds to start
    SERVER_CONNECT: 5000, // 5 seconds for server to accept connection

    // Default message timeout
    WORKER_MESSAGE: 3000, // 3 seconds default for messages

    // Per-message-type timeouts (override WORKER_MESSAGE)
    quickPing: 1000, // 1 second for quick operations
    slowProcess: 10000, // 10 seconds for slow operations
  };

  console.log('Timeout configuration:');
  console.log('  WORKER_STARTUP:', timeoutConfig.WORKER_STARTUP, 'ms');
  console.log('  SERVER_CONNECT:', timeoutConfig.SERVER_CONNECT, 'ms');
  console.log('  WORKER_MESSAGE:', timeoutConfig.WORKER_MESSAGE, 'ms');
  console.log('  quickPing:', timeoutConfig.quickPing, 'ms');
  console.log('  slowProcess:', timeoutConfig.slowProcess, 'ms');
  console.log();

  const worker = await createWorker<Messages>({
    script: join(__dirname, 'worker.ts'),
    timeout: timeoutConfig,
  });

  console.log(`Worker spawned with PID: ${worker.pid}\n`);

  try {
    // Test 1: Quick ping (should succeed within 1s timeout)
    console.log('--- Test 1: Quick Ping ---');
    const pingStart = Date.now();
    const pingResult = await worker.send('quickPing', { timestamp: pingStart });
    console.log(`Quick ping completed in ${pingResult.latency}ms\n`);

    // Test 2: Slow process that completes within timeout
    console.log('--- Test 2: Slow Process (within timeout) ---');
    const slowResult = await worker.send('slowProcess', { durationMs: 500 });
    console.log(`Slow process completed: ${slowResult.actualDuration}ms\n`);

    // Test 3: Demonstrate timeout (commented out to not fail the example)
    // Uncomment to see timeout behavior:
    // console.log('--- Test 3: Timeout Demo ---');
    // await worker.send('slowProcess', { durationMs: 15000 }); // Would timeout

    console.log('All operations completed successfully!');
  } catch (err) {
    console.error('Error:', (err as Error).message);
  } finally {
    await worker.close();
    console.log('Worker closed successfully');
  }
}

main().catch((err) => {
  console.error('Fatal error:', err);
  process.exit(1);
});
worker.ts
/**
 * Timeout Configuration Example - Worker (Server) Side
 */

import { startWorkerServer, Handlers } from 'isolated-workers';
import type { Messages } from './messages.js';

// Helper to simulate async work
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));

const handlers: Handlers<Messages> = {
  quickPing: ({ timestamp }) => {
    const now = Date.now();
    return { latency: now - timestamp };
  },

  slowProcess: async ({ durationMs }) => {
    console.log(`Worker: Starting slow process (${durationMs}ms)`);
    const start = Date.now();
    await sleep(durationMs);
    const actualDuration = Date.now() - start;
    console.log(`Worker: Slow process completed in ${actualDuration}ms`);
    return { completed: true, actualDuration };
  },
};

async function main() {
  console.log('Worker starting...');

  const server = await startWorkerServer(handlers);

  console.log('Worker ready');

  process.on('SIGTERM', async () => {
    await server.stop();
    process.exit(0);
  });
}

main().catch((err) => {
  console.error('Worker error:', err);
  process.exit(1);
});

Running the Example

Run the example

bash
pnpm run:timeout-config