scheduler-race-test-task.ts 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import { Logger, ScheduledTask } from '@vendure/core';
  2. import fs from 'fs';
  3. import path from 'path';
  4. const LOG_FILE = path.join(__dirname, '../../scheduler-race-log.json');
  5. const WORKER_ID = `worker-${process.pid}`;
  6. /**
  7. * A scheduled task designed to test for race conditions in the DefaultSchedulerStrategy.
  8. *
  9. * This task:
  10. * - Runs every 5 seconds
  11. * - Logs execution details with worker PID to a JSON file
  12. * - Simulates 2 seconds of work to increase the window for race conditions
  13. *
  14. * To test:
  15. * 1. Start multiple workers: `DB=postgres npm run dev:worker` (in separate terminals)
  16. * 2. Let them run for a minute or two
  17. * 3. Check the log file for duplicate triggerKeys from different workers
  18. *
  19. * If the same triggerKey appears with different workerIds, that's a race condition!
  20. */
  21. export const schedulerRaceTestTask = new ScheduledTask({
  22. id: 'scheduler-race-test',
  23. description: 'Tests for race conditions in scheduled task execution',
  24. // Every 5 seconds (6-part cron: seconds minutes hours day month weekday)
  25. schedule: '*/5 * * * * *',
  26. async execute({ injector }) {
  27. const startTime = new Date().toISOString();
  28. // Create a trigger key by rounding to nearest 5-second boundary
  29. // This groups executions that should have been the same trigger
  30. const triggerTime = new Date();
  31. triggerTime.setMilliseconds(0);
  32. triggerTime.setSeconds(Math.floor(triggerTime.getSeconds() / 5) * 5);
  33. const triggerKey = triggerTime.toISOString();
  34. Logger.info(`[${WORKER_ID}] ⏰ Starting scheduled task at ${startTime} (trigger: ${triggerKey})`);
  35. // Simulate some work (2 seconds) - increases the chance of detecting race conditions
  36. await new Promise(resolve => setTimeout(resolve, 2000));
  37. const endTime = new Date().toISOString();
  38. const logEntry = {
  39. workerId: WORKER_ID,
  40. triggerKey,
  41. startTime,
  42. endTime,
  43. };
  44. // Append to log file
  45. let logs: any[] = [];
  46. try {
  47. const existing = fs.readFileSync(LOG_FILE, 'utf-8');
  48. logs = JSON.parse(existing);
  49. } catch (e) {
  50. // File doesn't exist yet, that's fine
  51. }
  52. logs.push(logEntry);
  53. fs.writeFileSync(LOG_FILE, JSON.stringify(logs, null, 2));
  54. Logger.info(`[${WORKER_ID}] ✅ Finished scheduled task at ${endTime}`);
  55. return { workerId: WORKER_ID, triggerKey, startTime, endTime };
  56. },
  57. });