All files / services/workflow-service-worker/src worker.js

90.76% Statements 59/65
57.14% Branches 4/7
100% Functions 2/2
90.76% Lines 59/65

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 651x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x       1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x   1x 1x 1x 1x     1x
/**
 * Worker Temporal pour l'orchestration des workflows
 * Rôle: Exécution des workflows + activités (storage)
 */
 
const { Worker, NativeConnection } = require('@temporalio/worker');
const path = require('path');
const config = require('./shared/config');
const mongoose = require('mongoose');
const { resolveUrl } = require('./activities/resolve-url');
const { trackUsage, checkLlmBudget, checkOcrBudget } = require('./activities/track-usage');
 
async function runWorker() {
  console.log('[WorkflowWorker] Starting (orchestration + activities)...');
  console.log(`[WorkflowWorker] Temporal address: ${config.temporalAddress}`);
  console.log(`[WorkflowWorker] Task queue: ${config.temporalTaskQueue}`);
 
  // Connect to MongoDB
  try {
    await mongoose.connect(config.mongodbUri);
    console.log('[WorkflowWorker] Connected to MongoDB');
  } catch (error) {
    console.error('[WorkflowWorker] MongoDB connection failed:', error.message);
    process.exit(1);
  }
 
  // Connect to Temporal
  const connection = await NativeConnection.connect({
    address: config.temporalAddress
  });
 
  // Worker : workflows + activités métier (la persistance `jobs` est côté job-manager)
  const worker = await Worker.create({
    connection,
    namespace: 'default',
    taskQueue: config.temporalTaskQueue,
    workflowsPath: path.join(__dirname, 'workflows', 'workflow.js'),
    activities: { resolveUrl, trackUsage, checkLlmBudget, checkOcrBudget },
    // Laisse les activités en vol (resolveUrl…) se terminer avant l'arrêt forcé.
    shutdownGraceTime: '80s',
  });
 
  console.log('[WorkflowWorker] Workflow worker created, listening on:', config.temporalTaskQueue);
 
  // Drain : arrêt du polling + attente des tâches en vol (redéploiement sûr).
  let shuttingDown = false;
  const shutdown = (signal) => {
    if (shuttingDown) return;
    shuttingDown = true;
    console.log(`[WorkflowWorker] ${signal} received — draining in-flight activities (up to 80s)...`);
    worker.shutdown();
  };
  process.on('SIGINT', () => shutdown('SIGINT'));
  process.on('SIGTERM', () => shutdown('SIGTERM'));
 
  // Start workflow worker (résout une fois le drain terminé)
  await worker.run();
  console.log('[WorkflowWorker] Worker stopped');
}
 
// Run worker
runWorker().catch((error) => {
  console.error('[WorkflowWorker] Fatal error:', error);
  process.exit(1);
});