@zintrust/workers 0.1.28 → 0.1.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/README.md +16 -1
  2. package/dist/AnomalyDetection.d.ts +4 -0
  3. package/dist/AnomalyDetection.js +8 -0
  4. package/dist/BroadcastWorker.d.ts +2 -0
  5. package/dist/CanaryController.js +49 -5
  6. package/dist/ChaosEngineering.js +13 -0
  7. package/dist/ClusterLock.js +21 -10
  8. package/dist/DeadLetterQueue.js +12 -8
  9. package/dist/MultiQueueWorker.d.ts +1 -1
  10. package/dist/MultiQueueWorker.js +12 -7
  11. package/dist/NotificationWorker.d.ts +2 -0
  12. package/dist/PriorityQueue.d.ts +2 -2
  13. package/dist/PriorityQueue.js +20 -21
  14. package/dist/ResourceMonitor.js +65 -38
  15. package/dist/WorkerFactory.d.ts +23 -3
  16. package/dist/WorkerFactory.js +420 -40
  17. package/dist/WorkerInit.js +8 -3
  18. package/dist/WorkerMetrics.d.ts +2 -1
  19. package/dist/WorkerMetrics.js +152 -93
  20. package/dist/WorkerRegistry.d.ts +6 -0
  21. package/dist/WorkerRegistry.js +70 -1
  22. package/dist/WorkerShutdown.d.ts +21 -0
  23. package/dist/WorkerShutdown.js +82 -9
  24. package/dist/WorkerShutdownDurableObject.d.ts +12 -0
  25. package/dist/WorkerShutdownDurableObject.js +41 -0
  26. package/dist/build-manifest.json +171 -99
  27. package/dist/createQueueWorker.d.ts +2 -0
  28. package/dist/createQueueWorker.js +42 -27
  29. package/dist/dashboard/types.d.ts +5 -0
  30. package/dist/dashboard/workers-api.js +136 -43
  31. package/dist/http/WorkerApiController.js +1 -0
  32. package/dist/http/WorkerController.js +133 -85
  33. package/dist/http/WorkerMonitoringService.d.ts +11 -0
  34. package/dist/http/WorkerMonitoringService.js +62 -0
  35. package/dist/http/middleware/CustomValidation.js +1 -1
  36. package/dist/http/middleware/EditWorkerValidation.d.ts +1 -1
  37. package/dist/http/middleware/EditWorkerValidation.js +7 -6
  38. package/dist/http/middleware/ProcessorPathSanitizer.js +101 -35
  39. package/dist/http/middleware/WorkerValidationChain.js +1 -0
  40. package/dist/index.d.ts +2 -1
  41. package/dist/index.js +1 -0
  42. package/dist/routes/workers.js +48 -6
  43. package/dist/storage/WorkerStore.d.ts +4 -1
  44. package/dist/storage/WorkerStore.js +55 -7
  45. package/dist/telemetry/api/TelemetryAPI.d.ts +46 -0
  46. package/dist/telemetry/api/TelemetryAPI.js +219 -0
  47. package/dist/telemetry/api/TelemetryMonitoringService.d.ts +17 -0
  48. package/dist/telemetry/api/TelemetryMonitoringService.js +113 -0
  49. package/dist/telemetry/components/AlertPanel.d.ts +1 -0
  50. package/dist/telemetry/components/AlertPanel.js +13 -0
  51. package/dist/telemetry/components/CostTracking.d.ts +1 -0
  52. package/dist/telemetry/components/CostTracking.js +14 -0
  53. package/dist/telemetry/components/ResourceUsageChart.d.ts +1 -0
  54. package/dist/telemetry/components/ResourceUsageChart.js +11 -0
  55. package/dist/telemetry/components/WorkerHealthChart.d.ts +1 -0
  56. package/dist/telemetry/components/WorkerHealthChart.js +11 -0
  57. package/dist/telemetry/index.d.ts +15 -0
  58. package/dist/telemetry/index.js +60 -0
  59. package/dist/telemetry/routes/dashboard.d.ts +6 -0
  60. package/dist/telemetry/routes/dashboard.js +608 -0
  61. package/dist/ui/router/EmbeddedAssets.d.ts +4 -0
  62. package/dist/ui/router/EmbeddedAssets.js +13 -0
  63. package/dist/ui/router/ui.js +100 -4
  64. package/package.json +9 -5
  65. package/src/AnomalyDetection.ts +9 -0
  66. package/src/CanaryController.ts +41 -5
  67. package/src/ChaosEngineering.ts +14 -0
  68. package/src/ClusterLock.ts +22 -9
  69. package/src/DeadLetterQueue.ts +13 -8
  70. package/src/MultiQueueWorker.ts +15 -8
  71. package/src/PriorityQueue.ts +21 -22
  72. package/src/ResourceMonitor.ts +72 -40
  73. package/src/WorkerFactory.ts +545 -49
  74. package/src/WorkerInit.ts +8 -3
  75. package/src/WorkerMetrics.ts +183 -105
  76. package/src/WorkerRegistry.ts +80 -1
  77. package/src/WorkerShutdown.ts +115 -9
  78. package/src/WorkerShutdownDurableObject.ts +64 -0
  79. package/src/createQueueWorker.ts +73 -30
  80. package/src/dashboard/types.ts +5 -0
  81. package/src/dashboard/workers-api.ts +165 -52
  82. package/src/http/WorkerApiController.ts +1 -0
  83. package/src/http/WorkerController.ts +167 -90
  84. package/src/http/WorkerMonitoringService.ts +77 -0
  85. package/src/http/middleware/CustomValidation.ts +1 -1
  86. package/src/http/middleware/EditWorkerValidation.ts +7 -6
  87. package/src/http/middleware/ProcessorPathSanitizer.ts +123 -36
  88. package/src/http/middleware/WorkerValidationChain.ts +1 -0
  89. package/src/index.ts +6 -1
  90. package/src/routes/workers.ts +66 -9
  91. package/src/storage/WorkerStore.ts +59 -9
  92. package/src/telemetry/api/TelemetryAPI.ts +292 -0
  93. package/src/telemetry/api/TelemetryMonitoringService.ts +149 -0
  94. package/src/telemetry/components/AlertPanel.ts +13 -0
  95. package/src/telemetry/components/CostTracking.ts +14 -0
  96. package/src/telemetry/components/ResourceUsageChart.ts +11 -0
  97. package/src/telemetry/components/WorkerHealthChart.ts +11 -0
  98. package/src/telemetry/index.ts +121 -0
  99. package/src/telemetry/public/assets/zintrust-logo.svg +15 -0
  100. package/src/telemetry/routes/dashboard.ts +638 -0
  101. package/src/telemetry/styles/tailwind.css +1 -0
  102. package/src/telemetry/styles/zintrust-theme.css +8 -0
  103. package/src/ui/router/EmbeddedAssets.ts +13 -0
  104. package/src/ui/router/ui.ts +112 -5
  105. package/src/ui/workers/index.html +2 -2
  106. package/src/ui/workers/main.js +232 -61
  107. package/src/ui/workers/zintrust.svg +30 -0
  108. package/dist/dashboard/workers-dashboard-ui.d.ts +0 -3
  109. package/dist/dashboard/workers-dashboard-ui.js +0 -1026
  110. package/dist/dashboard/workers-dashboard.d.ts +0 -4
  111. package/dist/dashboard/workers-dashboard.js +0 -904
@@ -93,6 +93,16 @@ const safeUptime = () => {
93
93
  return 0;
94
94
  }
95
95
  };
96
+ const safeProcessCpuUsage = () => {
97
+ if (!process?.cpuUsage)
98
+ return { user: 0, system: 0 };
99
+ try {
100
+ return process.cpuUsage();
101
+ }
102
+ catch {
103
+ return { user: 0, system: 0 };
104
+ }
105
+ };
96
106
  // Default cost configuration (AWS-like pricing)
97
107
  const DEFAULT_COST_CONFIG = {
98
108
  computeCostPerCoreHour: 0.0416, // ~$0.0416 per vCPU hour (t3.medium equivalent)
@@ -106,6 +116,9 @@ let costConfig = { ...DEFAULT_COST_CONFIG };
106
116
  let monitoringInterval = null;
107
117
  const resourceHistory = new Map();
108
118
  const alertHistory = new Map();
119
+ // Memory management constants
120
+ const MAX_HISTORY_SIZE = 1000; // Keep last 1000 snapshots per worker
121
+ const MAX_ALERT_HISTORY = 100; // Keep last 100 alerts per worker
109
122
  // Resource thresholds
110
123
  const THRESHOLDS = {
111
124
  cpu: { warning: 70, critical: 90 },
@@ -113,30 +126,51 @@ const THRESHOLDS = {
113
126
  disk: { warning: 80, critical: 90 },
114
127
  costPerHour: { warning: 10, critical: 50 },
115
128
  };
116
- // Previous CPU usage for delta calculation
117
- let previousCpuUsage = null;
118
- let previousCpuTimestamp = null;
129
+ // Store previous CPU measurements for calculating real-time usage
130
+ let previousCpuTimes = null;
119
131
  /**
120
- * Helper: Calculate CPU usage percentage
132
+ * Helper: Calculate CPU usage percentage (real-time)
121
133
  */
122
134
  const calculateCpuUsage = () => {
123
- const currentCpuUsage = process.cpuUsage();
124
- const currentTimestamp = Date.now();
125
- if (previousCpuUsage === null || previousCpuTimestamp === null) {
126
- previousCpuUsage = currentCpuUsage;
127
- previousCpuTimestamp = currentTimestamp;
135
+ const os = getOsModule();
136
+ if (!os?.cpus)
128
137
  return 0;
129
- }
130
- const userDelta = currentCpuUsage.user - previousCpuUsage.user;
131
- const systemDelta = currentCpuUsage.system - previousCpuUsage.system;
132
- const timeDelta = (currentTimestamp - previousCpuTimestamp) * 1000; // Convert ms to microseconds
133
- previousCpuUsage = currentCpuUsage;
134
- previousCpuTimestamp = currentTimestamp;
135
- if (timeDelta === 0)
138
+ try {
139
+ const cpus = os.cpus();
140
+ let totalIdle = 0;
141
+ let totalTick = 0;
142
+ cpus.forEach((cpu) => {
143
+ for (const type in cpu.times) {
144
+ totalTick += cpu.times[type];
145
+ }
146
+ totalIdle += cpu.times.idle;
147
+ });
148
+ const now = Date.now();
149
+ // If we have previous measurements, calculate real-time usage
150
+ if (previousCpuTimes) {
151
+ const timeDiff = now - previousCpuTimes.timestamp;
152
+ // Only calculate if enough time has passed (minimum 100ms)
153
+ if (timeDiff >= 100) {
154
+ const idleDiff = totalIdle - previousCpuTimes.idle;
155
+ const totalDiff = totalTick - previousCpuTimes.total;
156
+ // Calculate CPU usage percentage for this interval
157
+ const cpuPercentage = totalDiff > 0 ? ((totalDiff - idleDiff) / totalDiff) * 100 : 0;
158
+ // Update previous measurements
159
+ previousCpuTimes = { idle: totalIdle, total: totalTick, timestamp: now };
160
+ return Math.min(100, Math.max(0, cpuPercentage));
161
+ }
162
+ }
163
+ // First measurement or not enough time passed
164
+ previousCpuTimes = { idle: totalIdle, total: totalTick, timestamp: now };
165
+ // For first call, return a reasonable estimate or use load average
166
+ const loadAvg = safeLoadAverage();
167
+ const cpuCount = safeCpuCount();
168
+ return Math.min(100, Math.max(0, (loadAvg[0] / cpuCount) * 100));
169
+ }
170
+ catch (error) {
171
+ Logger.error('Failed to calculate system CPU usage', error);
136
172
  return 0;
137
- const totalCpuDelta = userDelta + systemDelta;
138
- const cpuPercentage = (totalCpuDelta / timeDelta) * 100;
139
- return Math.min(100, Math.max(0, cpuPercentage));
173
+ }
140
174
  };
141
175
  /**
142
176
  * Helper: Get memory usage
@@ -181,7 +215,7 @@ const captureSnapshot = () => {
181
215
  pid: process.pid,
182
216
  uptime: process.uptime(),
183
217
  memoryUsage: process.memoryUsage(),
184
- cpuUsage: process.cpuUsage(),
218
+ cpuUsage: safeProcessCpuUsage(),
185
219
  },
186
220
  };
187
221
  };
@@ -333,16 +367,10 @@ const storeAlert = (alert) => {
333
367
  alertHistory.set(alert.workerName, history);
334
368
  }
335
369
  history.push(alert);
336
- // Keep only last 1000 alerts
337
- if (history.length > 1000) {
338
- history.shift();
339
- }
340
- Logger.warn(`Resource alert: ${alert.workerName}`, {
341
- type: alert.alertType,
342
- severity: alert.severity,
343
- message: alert.message,
344
- recommendation: alert.recommendation,
345
- });
370
+ // Trim alert history to prevent memory leaks
371
+ if (history.length > MAX_ALERT_HISTORY) {
372
+ alertHistory.set(alert.workerName, history.slice(-MAX_ALERT_HISTORY));
373
+ }
346
374
  };
347
375
  /**
348
376
  * Helper: Calculate trend
@@ -385,7 +413,7 @@ const calculateTrend = (workerName, metric, period) => {
385
413
  });
386
414
  // Simple linear regression for trend
387
415
  const firstValue = values[0];
388
- const lastValue = values.at(-1) ?? values[0];
416
+ const lastValue = values[values.length - 1] ?? values[0];
389
417
  const changePercentage = ((lastValue - firstValue) / firstValue) * 100;
390
418
  let trend;
391
419
  if (Math.abs(changePercentage) < 5) {
@@ -445,9 +473,6 @@ export const ResourceMonitor = Object.freeze({
445
473
  Logger.warn('ResourceMonitor already running');
446
474
  return;
447
475
  }
448
- // Initial snapshot
449
- previousCpuUsage = process.cpuUsage();
450
- previousCpuTimestamp = Date.now();
451
476
  monitoringInterval = setInterval(() => {
452
477
  const snapshot = captureSnapshot();
453
478
  // Store snapshot for later analysis
@@ -483,13 +508,15 @@ export const ResourceMonitor = Object.freeze({
483
508
  resourceHistory.set(workerName, history);
484
509
  }
485
510
  history.push(snapshot);
486
- // Keep only last 1000 snapshots
487
- if (history.length > 1000) {
488
- history.shift();
511
+ // Trim resource history to prevent memory leaks
512
+ if (history.length > MAX_HISTORY_SIZE) {
513
+ resourceHistory.set(workerName, history.slice(-MAX_HISTORY_SIZE));
489
514
  }
490
515
  // Check thresholds
491
516
  const alerts = checkThresholds(workerName, snapshot, cost);
492
- alerts.forEach(storeAlert);
517
+ alerts.forEach((element) => {
518
+ storeAlert(element);
519
+ });
493
520
  return {
494
521
  workerName,
495
522
  cpu: snapshot.cpu.usage,
@@ -24,9 +24,10 @@ export type WorkerFactoryConfig = {
24
24
  version?: string;
25
25
  queueName: string;
26
26
  processor: (job: Job) => Promise<unknown>;
27
- processorPath?: string;
27
+ processorSpec?: string;
28
28
  options?: WorkerOptions;
29
29
  autoStart?: boolean;
30
+ activeStatus?: boolean;
30
31
  infrastructure?: {
31
32
  redis?: RedisConfigInput;
32
33
  persistence?: WorkerPersistenceConfig;
@@ -98,7 +99,7 @@ type ObservabilityConfigInput = ObservabilityConfig | {
98
99
  openTelemetry?: Partial<ObservabilityConfig['openTelemetry']>;
99
100
  datadog?: Partial<ObservabilityConfig['datadog']>;
100
101
  };
101
- type ProcessorResolver = (name: string) => WorkerFactoryConfig['processor'] | undefined | Promise<WorkerFactoryConfig['processor'] | undefined>;
102
+ export type ProcessorResolver = (name: string) => WorkerFactoryConfig['processor'] | undefined | Promise<WorkerFactoryConfig['processor'] | undefined>;
102
103
  /**
103
104
  * Worker Factory - Sealed namespace
104
105
  */
@@ -107,7 +108,9 @@ export declare const WorkerFactory: Readonly<{
107
108
  registerProcessors: (processors: Record<string, WorkerFactoryConfig["processor"]>) => void;
108
109
  registerProcessorPaths: (paths: Record<string, string>) => void;
109
110
  registerProcessorResolver: (resolver: ProcessorResolver) => void;
111
+ registerProcessorSpec: (spec: string, processor: WorkerFactoryConfig["processor"]) => void;
110
112
  resolveProcessorPath: (modulePath: string) => Promise<WorkerFactoryConfig["processor"] | undefined>;
113
+ resolveProcessorSpec: (spec: string) => Promise<WorkerFactoryConfig["processor"] | undefined>;
111
114
  /**
112
115
  * Create new worker with full setup
113
116
  */
@@ -123,7 +126,9 @@ export declare const WorkerFactory: Readonly<{
123
126
  /**
124
127
  * Stop worker
125
128
  */
126
- stop(name: string, persistenceOverride?: WorkerPersistenceConfig): Promise<void>;
129
+ stop(name: string, persistenceOverride?: WorkerPersistenceConfig, options?: {
130
+ skipPersistedUpdate?: boolean;
131
+ }): Promise<void>;
127
132
  /**
128
133
  * Restart worker
129
134
  */
@@ -140,6 +145,14 @@ export declare const WorkerFactory: Readonly<{
140
145
  * Update auto-start for persisted worker
141
146
  */
142
147
  setAutoStart(name: string, autoStart: boolean, persistenceOverride?: WorkerPersistenceConfig): Promise<void>;
148
+ /**
149
+ * Update active status for a worker
150
+ */
151
+ setWorkerActiveStatus(name: string, activeStatus: boolean, persistenceOverride?: WorkerPersistenceConfig): Promise<void>;
152
+ /**
153
+ * Get active status for a worker
154
+ */
155
+ getWorkerActiveStatus(name: string, persistenceOverride?: WorkerPersistenceConfig): Promise<boolean | null>;
143
156
  /**
144
157
  * Update persisted worker record and in-memory config if running.
145
158
  */
@@ -159,11 +172,13 @@ export declare const WorkerFactory: Readonly<{
159
172
  offset?: number;
160
173
  limit?: number;
161
174
  search?: string;
175
+ includeInactive?: boolean;
162
176
  }): Promise<string[]>;
163
177
  listPersistedRecords(persistenceOverride?: WorkerPersistenceConfig, options?: {
164
178
  offset?: number;
165
179
  limit?: number;
166
180
  search?: string;
181
+ includeInactive?: boolean;
167
182
  }): Promise<WorkerRecord[]>;
168
183
  /**
169
184
  * Start a worker from persisted storage when it is not registered.
@@ -189,5 +204,10 @@ export declare const WorkerFactory: Readonly<{
189
204
  * Shutdown all workers
190
205
  */
191
206
  shutdown(): Promise<void>;
207
+ /**
208
+ * Reset persistence connection state.
209
+ * Useful when connections become stale in long-running processes or serverless environments.
210
+ */
211
+ resetPersistence(): Promise<void>;
192
212
  }>;
193
213
  export {};