@zintrust/workers 0.1.27

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 (178) hide show
  1. package/README.md +861 -0
  2. package/dist/AnomalyDetection.d.ts +102 -0
  3. package/dist/AnomalyDetection.js +321 -0
  4. package/dist/AutoScaler.d.ts +127 -0
  5. package/dist/AutoScaler.js +425 -0
  6. package/dist/BroadcastWorker.d.ts +21 -0
  7. package/dist/BroadcastWorker.js +24 -0
  8. package/dist/CanaryController.d.ts +103 -0
  9. package/dist/CanaryController.js +380 -0
  10. package/dist/ChaosEngineering.d.ts +79 -0
  11. package/dist/ChaosEngineering.js +216 -0
  12. package/dist/CircuitBreaker.d.ts +106 -0
  13. package/dist/CircuitBreaker.js +374 -0
  14. package/dist/ClusterLock.d.ts +90 -0
  15. package/dist/ClusterLock.js +385 -0
  16. package/dist/ComplianceManager.d.ts +177 -0
  17. package/dist/ComplianceManager.js +556 -0
  18. package/dist/DatacenterOrchestrator.d.ts +133 -0
  19. package/dist/DatacenterOrchestrator.js +404 -0
  20. package/dist/DeadLetterQueue.d.ts +122 -0
  21. package/dist/DeadLetterQueue.js +539 -0
  22. package/dist/HealthMonitor.d.ts +42 -0
  23. package/dist/HealthMonitor.js +301 -0
  24. package/dist/MultiQueueWorker.d.ts +89 -0
  25. package/dist/MultiQueueWorker.js +277 -0
  26. package/dist/NotificationWorker.d.ts +21 -0
  27. package/dist/NotificationWorker.js +23 -0
  28. package/dist/Observability.d.ts +153 -0
  29. package/dist/Observability.js +530 -0
  30. package/dist/PluginManager.d.ts +123 -0
  31. package/dist/PluginManager.js +392 -0
  32. package/dist/PriorityQueue.d.ts +117 -0
  33. package/dist/PriorityQueue.js +244 -0
  34. package/dist/ResourceMonitor.d.ts +164 -0
  35. package/dist/ResourceMonitor.js +605 -0
  36. package/dist/SLAMonitor.d.ts +110 -0
  37. package/dist/SLAMonitor.js +274 -0
  38. package/dist/WorkerFactory.d.ts +193 -0
  39. package/dist/WorkerFactory.js +1507 -0
  40. package/dist/WorkerInit.d.ts +85 -0
  41. package/dist/WorkerInit.js +223 -0
  42. package/dist/WorkerMetrics.d.ts +114 -0
  43. package/dist/WorkerMetrics.js +509 -0
  44. package/dist/WorkerRegistry.d.ts +145 -0
  45. package/dist/WorkerRegistry.js +319 -0
  46. package/dist/WorkerShutdown.d.ts +61 -0
  47. package/dist/WorkerShutdown.js +159 -0
  48. package/dist/WorkerVersioning.d.ts +107 -0
  49. package/dist/WorkerVersioning.js +300 -0
  50. package/dist/build-manifest.json +462 -0
  51. package/dist/config/workerConfig.d.ts +3 -0
  52. package/dist/config/workerConfig.js +19 -0
  53. package/dist/createQueueWorker.d.ts +23 -0
  54. package/dist/createQueueWorker.js +113 -0
  55. package/dist/dashboard/index.d.ts +1 -0
  56. package/dist/dashboard/index.js +1 -0
  57. package/dist/dashboard/types.d.ts +117 -0
  58. package/dist/dashboard/types.js +1 -0
  59. package/dist/dashboard/workers-api.d.ts +4 -0
  60. package/dist/dashboard/workers-api.js +638 -0
  61. package/dist/dashboard/workers-dashboard-ui.d.ts +3 -0
  62. package/dist/dashboard/workers-dashboard-ui.js +1026 -0
  63. package/dist/dashboard/workers-dashboard.d.ts +4 -0
  64. package/dist/dashboard/workers-dashboard.js +904 -0
  65. package/dist/helper/index.d.ts +5 -0
  66. package/dist/helper/index.js +10 -0
  67. package/dist/http/WorkerApiController.d.ts +38 -0
  68. package/dist/http/WorkerApiController.js +312 -0
  69. package/dist/http/WorkerController.d.ts +374 -0
  70. package/dist/http/WorkerController.js +1351 -0
  71. package/dist/http/middleware/CustomValidation.d.ts +92 -0
  72. package/dist/http/middleware/CustomValidation.js +270 -0
  73. package/dist/http/middleware/DatacenterValidator.d.ts +3 -0
  74. package/dist/http/middleware/DatacenterValidator.js +94 -0
  75. package/dist/http/middleware/EditWorkerValidation.d.ts +7 -0
  76. package/dist/http/middleware/EditWorkerValidation.js +55 -0
  77. package/dist/http/middleware/FeaturesValidator.d.ts +3 -0
  78. package/dist/http/middleware/FeaturesValidator.js +60 -0
  79. package/dist/http/middleware/InfrastructureValidator.d.ts +31 -0
  80. package/dist/http/middleware/InfrastructureValidator.js +226 -0
  81. package/dist/http/middleware/OptionsValidator.d.ts +3 -0
  82. package/dist/http/middleware/OptionsValidator.js +112 -0
  83. package/dist/http/middleware/PayloadSanitizer.d.ts +7 -0
  84. package/dist/http/middleware/PayloadSanitizer.js +42 -0
  85. package/dist/http/middleware/ProcessorPathSanitizer.d.ts +3 -0
  86. package/dist/http/middleware/ProcessorPathSanitizer.js +74 -0
  87. package/dist/http/middleware/QueueNameSanitizer.d.ts +3 -0
  88. package/dist/http/middleware/QueueNameSanitizer.js +45 -0
  89. package/dist/http/middleware/ValidateDriver.d.ts +7 -0
  90. package/dist/http/middleware/ValidateDriver.js +20 -0
  91. package/dist/http/middleware/VersionSanitizer.d.ts +3 -0
  92. package/dist/http/middleware/VersionSanitizer.js +25 -0
  93. package/dist/http/middleware/WorkerNameSanitizer.d.ts +3 -0
  94. package/dist/http/middleware/WorkerNameSanitizer.js +46 -0
  95. package/dist/http/middleware/WorkerValidationChain.d.ts +27 -0
  96. package/dist/http/middleware/WorkerValidationChain.js +185 -0
  97. package/dist/index.d.ts +46 -0
  98. package/dist/index.js +48 -0
  99. package/dist/routes/workers.d.ts +12 -0
  100. package/dist/routes/workers.js +81 -0
  101. package/dist/storage/WorkerStore.d.ts +45 -0
  102. package/dist/storage/WorkerStore.js +195 -0
  103. package/dist/type.d.ts +76 -0
  104. package/dist/type.js +1 -0
  105. package/dist/ui/router/ui.d.ts +3 -0
  106. package/dist/ui/router/ui.js +83 -0
  107. package/dist/ui/types/worker-ui.d.ts +229 -0
  108. package/dist/ui/types/worker-ui.js +5 -0
  109. package/package.json +53 -0
  110. package/src/AnomalyDetection.ts +434 -0
  111. package/src/AutoScaler.ts +654 -0
  112. package/src/BroadcastWorker.ts +34 -0
  113. package/src/CanaryController.ts +531 -0
  114. package/src/ChaosEngineering.ts +301 -0
  115. package/src/CircuitBreaker.ts +495 -0
  116. package/src/ClusterLock.ts +499 -0
  117. package/src/ComplianceManager.ts +815 -0
  118. package/src/DatacenterOrchestrator.ts +561 -0
  119. package/src/DeadLetterQueue.ts +733 -0
  120. package/src/HealthMonitor.ts +390 -0
  121. package/src/MultiQueueWorker.ts +431 -0
  122. package/src/NotificationWorker.ts +33 -0
  123. package/src/Observability.ts +696 -0
  124. package/src/PluginManager.ts +551 -0
  125. package/src/PriorityQueue.ts +351 -0
  126. package/src/ResourceMonitor.ts +769 -0
  127. package/src/SLAMonitor.ts +408 -0
  128. package/src/WorkerFactory.ts +2108 -0
  129. package/src/WorkerInit.ts +313 -0
  130. package/src/WorkerMetrics.ts +709 -0
  131. package/src/WorkerRegistry.ts +443 -0
  132. package/src/WorkerShutdown.ts +210 -0
  133. package/src/WorkerVersioning.ts +422 -0
  134. package/src/config/workerConfig.ts +25 -0
  135. package/src/createQueueWorker.ts +174 -0
  136. package/src/dashboard/index.ts +6 -0
  137. package/src/dashboard/types.ts +141 -0
  138. package/src/dashboard/workers-api.ts +785 -0
  139. package/src/dashboard/zintrust.svg +30 -0
  140. package/src/helper/index.ts +11 -0
  141. package/src/http/WorkerApiController.ts +369 -0
  142. package/src/http/WorkerController.ts +1512 -0
  143. package/src/http/middleware/CustomValidation.ts +360 -0
  144. package/src/http/middleware/DatacenterValidator.ts +124 -0
  145. package/src/http/middleware/EditWorkerValidation.ts +74 -0
  146. package/src/http/middleware/FeaturesValidator.ts +82 -0
  147. package/src/http/middleware/InfrastructureValidator.ts +295 -0
  148. package/src/http/middleware/OptionsValidator.ts +144 -0
  149. package/src/http/middleware/PayloadSanitizer.ts +52 -0
  150. package/src/http/middleware/ProcessorPathSanitizer.ts +86 -0
  151. package/src/http/middleware/QueueNameSanitizer.ts +55 -0
  152. package/src/http/middleware/ValidateDriver.ts +29 -0
  153. package/src/http/middleware/VersionSanitizer.ts +30 -0
  154. package/src/http/middleware/WorkerNameSanitizer.ts +56 -0
  155. package/src/http/middleware/WorkerValidationChain.ts +230 -0
  156. package/src/index.ts +98 -0
  157. package/src/routes/workers.ts +154 -0
  158. package/src/storage/WorkerStore.ts +240 -0
  159. package/src/type.ts +89 -0
  160. package/src/types/queue-monitor.d.ts +38 -0
  161. package/src/types/queue-redis.d.ts +38 -0
  162. package/src/ui/README.md +13 -0
  163. package/src/ui/components/JsonEditor.js +670 -0
  164. package/src/ui/components/JsonViewer.js +387 -0
  165. package/src/ui/components/WorkerCard.js +178 -0
  166. package/src/ui/components/WorkerExpandPanel.js +257 -0
  167. package/src/ui/components/fetcher.js +42 -0
  168. package/src/ui/components/sla-scorecard.js +32 -0
  169. package/src/ui/components/styles.css +30 -0
  170. package/src/ui/components/table-expander.js +34 -0
  171. package/src/ui/integration/worker-ui-integration.js +565 -0
  172. package/src/ui/router/ui.ts +99 -0
  173. package/src/ui/services/workerApi.js +240 -0
  174. package/src/ui/types/worker-ui.ts +283 -0
  175. package/src/ui/utils/jsonValidator.js +444 -0
  176. package/src/ui/workers/index.html +202 -0
  177. package/src/ui/workers/main.js +1781 -0
  178. package/src/ui/workers/styles.css +1350 -0
@@ -0,0 +1,301 @@
1
+ /**
2
+ * Chaos Engineering
3
+ * Controlled fault injection experiments for worker resilience testing
4
+ * Sealed namespace for immutability
5
+ */
6
+
7
+ import { ErrorFactory, Logger, generateUuid } from '@zintrust/core';
8
+ import { CircuitBreaker } from './CircuitBreaker';
9
+ import { Observability } from './Observability';
10
+ import { ResourceMonitor } from './ResourceMonitor';
11
+ import { WorkerRegistry } from './WorkerRegistry';
12
+
13
+ export interface IChaosExperiment {
14
+ name: string;
15
+ description: string;
16
+ target: {
17
+ workers?: string[];
18
+ percentage?: number;
19
+ };
20
+ failure: {
21
+ type: 'crash' | 'latency' | 'error' | 'resource';
22
+ config: unknown;
23
+ };
24
+ duration: number; // milliseconds
25
+ safetyLimits: {
26
+ maxConcurrent: number;
27
+ circuitBreaker: boolean;
28
+ rollbackOn: string[];
29
+ };
30
+ }
31
+
32
+ export type IChaosStatus = {
33
+ id: string;
34
+ name: string;
35
+ state: 'defined' | 'running' | 'completed' | 'stopped' | 'failed';
36
+ startedAt: Date | null;
37
+ endedAt: Date | null;
38
+ targetedWorkers: string[];
39
+ failureType: IChaosExperiment['failure']['type'];
40
+ };
41
+
42
+ export type IChaosReport = {
43
+ experimentId: string;
44
+ summary: string;
45
+ durationMs: number;
46
+ targetedWorkers: string[];
47
+ completedAt: Date | null;
48
+ };
49
+
50
+ export type IChaosComparison = {
51
+ comparedIds: string[];
52
+ running: number;
53
+ completed: number;
54
+ stopped: number;
55
+ };
56
+
57
+ type ExperimentRecord = {
58
+ config: IChaosExperiment;
59
+ status: IChaosStatus;
60
+ timer: NodeJS.Timeout | null;
61
+ };
62
+
63
+ const experiments = new Map<string, ExperimentRecord>();
64
+
65
+ const getTargetWorkers = (config: IChaosExperiment): string[] => {
66
+ const candidates = config.target.workers ?? WorkerRegistry.listRunning();
67
+ if (candidates.length === 0) return [];
68
+
69
+ const percentage = config.target.percentage ?? 100;
70
+ if (percentage >= 100) return [...candidates];
71
+
72
+ const count = Math.max(1, Math.floor((candidates.length * percentage) / 100));
73
+ return candidates.slice(0, count);
74
+ };
75
+
76
+ const applyFailure = async (config: IChaosExperiment, workers: string[]): Promise<void> => {
77
+ switch (config.failure.type) {
78
+ case 'crash':
79
+ await Promise.all(
80
+ workers.map(async (workerName) => {
81
+ try {
82
+ await WorkerRegistry.stop(workerName);
83
+ } catch (error) {
84
+ Logger.error(`Failed to inject crash for ${workerName}`, error);
85
+ }
86
+ })
87
+ );
88
+ break;
89
+ case 'latency':
90
+ workers.forEach((workerName) => {
91
+ Logger.warn(`Injected latency for ${workerName}`, { config: config.failure.config });
92
+ });
93
+ break;
94
+ case 'error':
95
+ workers.forEach((workerName) => {
96
+ const status = WorkerRegistry.status(workerName);
97
+ if (status) {
98
+ CircuitBreaker.forceOpen(workerName, status.version, 'Chaos experiment error injection');
99
+ }
100
+ });
101
+ break;
102
+ case 'resource':
103
+ workers.forEach((workerName) => {
104
+ const usage = ResourceMonitor.getCurrentUsage(workerName);
105
+ Logger.warn(`Resource pressure simulated for ${workerName}`, {
106
+ cpu: usage.cpu,
107
+ memory: usage.memory.percent,
108
+ config: config.failure.config,
109
+ });
110
+ });
111
+ break;
112
+ }
113
+
114
+ if (Observability.isEnabled()) {
115
+ workers.forEach((workerName) => {
116
+ Observability.recordJobMetrics(workerName, 'chaos', {
117
+ processed: 0,
118
+ failed: 0,
119
+ });
120
+ });
121
+ }
122
+ };
123
+
124
+ const rollbackFailure = (config: IChaosExperiment, workers: string[]): void => {
125
+ if (!config.safetyLimits.circuitBreaker) return;
126
+
127
+ if (config.failure.type === 'error') {
128
+ workers.forEach((workerName) => {
129
+ const status = WorkerRegistry.status(workerName);
130
+ if (status) {
131
+ CircuitBreaker.reset(workerName, status.version);
132
+ }
133
+ });
134
+ }
135
+ };
136
+
137
+ /**
138
+ * Chaos Engineering - Sealed namespace
139
+ */
140
+ export const ChaosEngineering = Object.freeze({
141
+ /**
142
+ * Define a chaos experiment
143
+ */
144
+ defineExperiment(config: IChaosExperiment): string {
145
+ const id = generateUuid();
146
+ const status: IChaosStatus = {
147
+ id,
148
+ name: config.name,
149
+ state: 'defined',
150
+ startedAt: null,
151
+ endedAt: null,
152
+ targetedWorkers: [],
153
+ failureType: config.failure.type,
154
+ };
155
+
156
+ experiments.set(id, { config, status, timer: null });
157
+ Logger.info(`Chaos experiment defined: ${config.name}`, { id });
158
+ return id;
159
+ },
160
+
161
+ /**
162
+ * Start a chaos experiment
163
+ */
164
+ async startExperiment(experimentId: string): Promise<void> {
165
+ const record = experiments.get(experimentId);
166
+ if (!record) {
167
+ throw ErrorFactory.createNotFoundError(`Chaos experiment not found: ${experimentId}`);
168
+ }
169
+
170
+ if (record.status.state === 'running') {
171
+ throw ErrorFactory.createWorkerError(`Chaos experiment already running: ${experimentId}`);
172
+ }
173
+
174
+ const runningCount = Array.from(experiments.values()).filter(
175
+ (exp) => exp.status.state === 'running'
176
+ ).length;
177
+
178
+ if (runningCount >= record.config.safetyLimits.maxConcurrent) {
179
+ throw ErrorFactory.createWorkerError('Maximum concurrent chaos experiments reached');
180
+ }
181
+
182
+ const targets = getTargetWorkers(record.config);
183
+ record.status.state = 'running';
184
+ record.status.startedAt = new Date();
185
+ record.status.targetedWorkers = targets;
186
+
187
+ Logger.warn(`Chaos experiment started: ${record.config.name}`, {
188
+ id: experimentId,
189
+ targets,
190
+ });
191
+
192
+ await applyFailure(record.config, targets);
193
+
194
+ record.timer = globalThis.setTimeout(() => {
195
+ const currentTimer = record.timer;
196
+ record.timer = null;
197
+ ChaosEngineering.stopExperiment(experimentId).catch((error) => {
198
+ Logger.error('Failed to stop chaos experiment after duration', error);
199
+ if (currentTimer) clearTimeout(currentTimer);
200
+ });
201
+ }, record.config.duration);
202
+ },
203
+
204
+ /**
205
+ * Stop a chaos experiment
206
+ */
207
+ async stopExperiment(experimentId: string): Promise<void> {
208
+ const record = experiments.get(experimentId);
209
+ if (!record) {
210
+ throw ErrorFactory.createNotFoundError(`Chaos experiment not found: ${experimentId}`);
211
+ }
212
+
213
+ if (record.timer) {
214
+ clearTimeout(record.timer);
215
+ record.timer = null;
216
+ }
217
+
218
+ rollbackFailure(record.config, record.status.targetedWorkers);
219
+
220
+ record.status.state = 'completed';
221
+ record.status.endedAt = new Date();
222
+
223
+ Logger.info(`Chaos experiment completed: ${record.config.name}`, {
224
+ id: experimentId,
225
+ duration: record.config.duration,
226
+ });
227
+ },
228
+
229
+ /**
230
+ * Get experiment status
231
+ */
232
+ getExperimentStatus(experimentId: string): IChaosStatus {
233
+ const record = experiments.get(experimentId);
234
+ if (!record) {
235
+ throw ErrorFactory.createNotFoundError(`Chaos experiment not found: ${experimentId}`);
236
+ }
237
+
238
+ return { ...record.status, targetedWorkers: [...record.status.targetedWorkers] };
239
+ },
240
+
241
+ /**
242
+ * Failure injection helpers
243
+ */
244
+ injectCrash(workerName: string): void {
245
+ WorkerRegistry.stop(workerName).catch((error) => {
246
+ Logger.error(`Failed to inject crash for ${workerName}`, error);
247
+ });
248
+ },
249
+
250
+ injectLatency(workerName: string, delayMs: number): void {
251
+ Logger.warn(`Injected latency ${delayMs}ms for ${workerName}`);
252
+ },
253
+
254
+ injectError(workerName: string, errorRate: number): void {
255
+ const status = WorkerRegistry.status(workerName);
256
+ if (!status) {
257
+ throw ErrorFactory.createNotFoundError(`Worker not found: ${workerName}`);
258
+ }
259
+
260
+ CircuitBreaker.forceOpen(workerName, status.version, `Chaos error rate ${errorRate}`);
261
+ },
262
+
263
+ injectResourceExhaustion(workerName: string, type: 'cpu' | 'memory'): void {
264
+ const usage = ResourceMonitor.getCurrentUsage(workerName);
265
+ Logger.warn(`Injected resource exhaustion (${type}) for ${workerName}`, {
266
+ cpu: usage.cpu,
267
+ memory: usage.memory.percent,
268
+ });
269
+ },
270
+
271
+ /**
272
+ * Analysis helpers
273
+ */
274
+ analyzeResilience(experimentId: string): IChaosReport {
275
+ const record = experiments.get(experimentId);
276
+ if (!record) {
277
+ throw ErrorFactory.createNotFoundError(`Chaos experiment not found: ${experimentId}`);
278
+ }
279
+
280
+ return {
281
+ experimentId,
282
+ summary: `Experiment ${record.config.name} finished with ${record.status.state}`,
283
+ durationMs: record.config.duration,
284
+ targetedWorkers: [...record.status.targetedWorkers],
285
+ completedAt: record.status.endedAt,
286
+ };
287
+ },
288
+
289
+ compareExperiments(ids: string[]): IChaosComparison {
290
+ const statuses = ids.map((id) => experiments.get(id)?.status).filter(Boolean) as IChaosStatus[];
291
+
292
+ return {
293
+ comparedIds: ids,
294
+ running: statuses.filter((s) => s.state === 'running').length,
295
+ completed: statuses.filter((s) => s.state === 'completed').length,
296
+ stopped: statuses.filter((s) => s.state === 'stopped').length,
297
+ };
298
+ },
299
+ });
300
+
301
+ export default ChaosEngineering;