@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.
- package/README.md +861 -0
- package/dist/AnomalyDetection.d.ts +102 -0
- package/dist/AnomalyDetection.js +321 -0
- package/dist/AutoScaler.d.ts +127 -0
- package/dist/AutoScaler.js +425 -0
- package/dist/BroadcastWorker.d.ts +21 -0
- package/dist/BroadcastWorker.js +24 -0
- package/dist/CanaryController.d.ts +103 -0
- package/dist/CanaryController.js +380 -0
- package/dist/ChaosEngineering.d.ts +79 -0
- package/dist/ChaosEngineering.js +216 -0
- package/dist/CircuitBreaker.d.ts +106 -0
- package/dist/CircuitBreaker.js +374 -0
- package/dist/ClusterLock.d.ts +90 -0
- package/dist/ClusterLock.js +385 -0
- package/dist/ComplianceManager.d.ts +177 -0
- package/dist/ComplianceManager.js +556 -0
- package/dist/DatacenterOrchestrator.d.ts +133 -0
- package/dist/DatacenterOrchestrator.js +404 -0
- package/dist/DeadLetterQueue.d.ts +122 -0
- package/dist/DeadLetterQueue.js +539 -0
- package/dist/HealthMonitor.d.ts +42 -0
- package/dist/HealthMonitor.js +301 -0
- package/dist/MultiQueueWorker.d.ts +89 -0
- package/dist/MultiQueueWorker.js +277 -0
- package/dist/NotificationWorker.d.ts +21 -0
- package/dist/NotificationWorker.js +23 -0
- package/dist/Observability.d.ts +153 -0
- package/dist/Observability.js +530 -0
- package/dist/PluginManager.d.ts +123 -0
- package/dist/PluginManager.js +392 -0
- package/dist/PriorityQueue.d.ts +117 -0
- package/dist/PriorityQueue.js +244 -0
- package/dist/ResourceMonitor.d.ts +164 -0
- package/dist/ResourceMonitor.js +605 -0
- package/dist/SLAMonitor.d.ts +110 -0
- package/dist/SLAMonitor.js +274 -0
- package/dist/WorkerFactory.d.ts +193 -0
- package/dist/WorkerFactory.js +1507 -0
- package/dist/WorkerInit.d.ts +85 -0
- package/dist/WorkerInit.js +223 -0
- package/dist/WorkerMetrics.d.ts +114 -0
- package/dist/WorkerMetrics.js +509 -0
- package/dist/WorkerRegistry.d.ts +145 -0
- package/dist/WorkerRegistry.js +319 -0
- package/dist/WorkerShutdown.d.ts +61 -0
- package/dist/WorkerShutdown.js +159 -0
- package/dist/WorkerVersioning.d.ts +107 -0
- package/dist/WorkerVersioning.js +300 -0
- package/dist/build-manifest.json +462 -0
- package/dist/config/workerConfig.d.ts +3 -0
- package/dist/config/workerConfig.js +19 -0
- package/dist/createQueueWorker.d.ts +23 -0
- package/dist/createQueueWorker.js +113 -0
- package/dist/dashboard/index.d.ts +1 -0
- package/dist/dashboard/index.js +1 -0
- package/dist/dashboard/types.d.ts +117 -0
- package/dist/dashboard/types.js +1 -0
- package/dist/dashboard/workers-api.d.ts +4 -0
- package/dist/dashboard/workers-api.js +638 -0
- package/dist/dashboard/workers-dashboard-ui.d.ts +3 -0
- package/dist/dashboard/workers-dashboard-ui.js +1026 -0
- package/dist/dashboard/workers-dashboard.d.ts +4 -0
- package/dist/dashboard/workers-dashboard.js +904 -0
- package/dist/helper/index.d.ts +5 -0
- package/dist/helper/index.js +10 -0
- package/dist/http/WorkerApiController.d.ts +38 -0
- package/dist/http/WorkerApiController.js +312 -0
- package/dist/http/WorkerController.d.ts +374 -0
- package/dist/http/WorkerController.js +1351 -0
- package/dist/http/middleware/CustomValidation.d.ts +92 -0
- package/dist/http/middleware/CustomValidation.js +270 -0
- package/dist/http/middleware/DatacenterValidator.d.ts +3 -0
- package/dist/http/middleware/DatacenterValidator.js +94 -0
- package/dist/http/middleware/EditWorkerValidation.d.ts +7 -0
- package/dist/http/middleware/EditWorkerValidation.js +55 -0
- package/dist/http/middleware/FeaturesValidator.d.ts +3 -0
- package/dist/http/middleware/FeaturesValidator.js +60 -0
- package/dist/http/middleware/InfrastructureValidator.d.ts +31 -0
- package/dist/http/middleware/InfrastructureValidator.js +226 -0
- package/dist/http/middleware/OptionsValidator.d.ts +3 -0
- package/dist/http/middleware/OptionsValidator.js +112 -0
- package/dist/http/middleware/PayloadSanitizer.d.ts +7 -0
- package/dist/http/middleware/PayloadSanitizer.js +42 -0
- package/dist/http/middleware/ProcessorPathSanitizer.d.ts +3 -0
- package/dist/http/middleware/ProcessorPathSanitizer.js +74 -0
- package/dist/http/middleware/QueueNameSanitizer.d.ts +3 -0
- package/dist/http/middleware/QueueNameSanitizer.js +45 -0
- package/dist/http/middleware/ValidateDriver.d.ts +7 -0
- package/dist/http/middleware/ValidateDriver.js +20 -0
- package/dist/http/middleware/VersionSanitizer.d.ts +3 -0
- package/dist/http/middleware/VersionSanitizer.js +25 -0
- package/dist/http/middleware/WorkerNameSanitizer.d.ts +3 -0
- package/dist/http/middleware/WorkerNameSanitizer.js +46 -0
- package/dist/http/middleware/WorkerValidationChain.d.ts +27 -0
- package/dist/http/middleware/WorkerValidationChain.js +185 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +48 -0
- package/dist/routes/workers.d.ts +12 -0
- package/dist/routes/workers.js +81 -0
- package/dist/storage/WorkerStore.d.ts +45 -0
- package/dist/storage/WorkerStore.js +195 -0
- package/dist/type.d.ts +76 -0
- package/dist/type.js +1 -0
- package/dist/ui/router/ui.d.ts +3 -0
- package/dist/ui/router/ui.js +83 -0
- package/dist/ui/types/worker-ui.d.ts +229 -0
- package/dist/ui/types/worker-ui.js +5 -0
- package/package.json +53 -0
- package/src/AnomalyDetection.ts +434 -0
- package/src/AutoScaler.ts +654 -0
- package/src/BroadcastWorker.ts +34 -0
- package/src/CanaryController.ts +531 -0
- package/src/ChaosEngineering.ts +301 -0
- package/src/CircuitBreaker.ts +495 -0
- package/src/ClusterLock.ts +499 -0
- package/src/ComplianceManager.ts +815 -0
- package/src/DatacenterOrchestrator.ts +561 -0
- package/src/DeadLetterQueue.ts +733 -0
- package/src/HealthMonitor.ts +390 -0
- package/src/MultiQueueWorker.ts +431 -0
- package/src/NotificationWorker.ts +33 -0
- package/src/Observability.ts +696 -0
- package/src/PluginManager.ts +551 -0
- package/src/PriorityQueue.ts +351 -0
- package/src/ResourceMonitor.ts +769 -0
- package/src/SLAMonitor.ts +408 -0
- package/src/WorkerFactory.ts +2108 -0
- package/src/WorkerInit.ts +313 -0
- package/src/WorkerMetrics.ts +709 -0
- package/src/WorkerRegistry.ts +443 -0
- package/src/WorkerShutdown.ts +210 -0
- package/src/WorkerVersioning.ts +422 -0
- package/src/config/workerConfig.ts +25 -0
- package/src/createQueueWorker.ts +174 -0
- package/src/dashboard/index.ts +6 -0
- package/src/dashboard/types.ts +141 -0
- package/src/dashboard/workers-api.ts +785 -0
- package/src/dashboard/zintrust.svg +30 -0
- package/src/helper/index.ts +11 -0
- package/src/http/WorkerApiController.ts +369 -0
- package/src/http/WorkerController.ts +1512 -0
- package/src/http/middleware/CustomValidation.ts +360 -0
- package/src/http/middleware/DatacenterValidator.ts +124 -0
- package/src/http/middleware/EditWorkerValidation.ts +74 -0
- package/src/http/middleware/FeaturesValidator.ts +82 -0
- package/src/http/middleware/InfrastructureValidator.ts +295 -0
- package/src/http/middleware/OptionsValidator.ts +144 -0
- package/src/http/middleware/PayloadSanitizer.ts +52 -0
- package/src/http/middleware/ProcessorPathSanitizer.ts +86 -0
- package/src/http/middleware/QueueNameSanitizer.ts +55 -0
- package/src/http/middleware/ValidateDriver.ts +29 -0
- package/src/http/middleware/VersionSanitizer.ts +30 -0
- package/src/http/middleware/WorkerNameSanitizer.ts +56 -0
- package/src/http/middleware/WorkerValidationChain.ts +230 -0
- package/src/index.ts +98 -0
- package/src/routes/workers.ts +154 -0
- package/src/storage/WorkerStore.ts +240 -0
- package/src/type.ts +89 -0
- package/src/types/queue-monitor.d.ts +38 -0
- package/src/types/queue-redis.d.ts +38 -0
- package/src/ui/README.md +13 -0
- package/src/ui/components/JsonEditor.js +670 -0
- package/src/ui/components/JsonViewer.js +387 -0
- package/src/ui/components/WorkerCard.js +178 -0
- package/src/ui/components/WorkerExpandPanel.js +257 -0
- package/src/ui/components/fetcher.js +42 -0
- package/src/ui/components/sla-scorecard.js +32 -0
- package/src/ui/components/styles.css +30 -0
- package/src/ui/components/table-expander.js +34 -0
- package/src/ui/integration/worker-ui-integration.js +565 -0
- package/src/ui/router/ui.ts +99 -0
- package/src/ui/services/workerApi.js +240 -0
- package/src/ui/types/worker-ui.ts +283 -0
- package/src/ui/utils/jsonValidator.js +444 -0
- package/src/ui/workers/index.html +202 -0
- package/src/ui/workers/main.js +1781 -0
- package/src/ui/workers/styles.css +1350 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { Logger } from '@zintrust/core';
|
|
2
|
+
// Import individual validators
|
|
3
|
+
import { withDatacenterValidation } from './DatacenterValidator';
|
|
4
|
+
import { withFeaturesValidation } from './FeaturesValidator';
|
|
5
|
+
import { withInfrastructureValidation } from './InfrastructureValidator';
|
|
6
|
+
import { withOptionsValidation } from './OptionsValidator';
|
|
7
|
+
import { withStrictPayloadKeys } from './PayloadSanitizer';
|
|
8
|
+
import { withProcessorPathValidation } from './ProcessorPathSanitizer';
|
|
9
|
+
import { withQueueNameValidation } from './QueueNameSanitizer';
|
|
10
|
+
import { withVersionValidation } from './VersionSanitizer';
|
|
11
|
+
import { withWorkerNameValidation } from './WorkerNameSanitizer';
|
|
12
|
+
/**
|
|
13
|
+
* Composite middleware for worker creation validation
|
|
14
|
+
* Validates all required fields for creating a new worker
|
|
15
|
+
*/
|
|
16
|
+
export const withCreateWorkerValidation = (handler) => {
|
|
17
|
+
return withStrictPayloadKeys([
|
|
18
|
+
'name',
|
|
19
|
+
'queueName',
|
|
20
|
+
'processor',
|
|
21
|
+
'version',
|
|
22
|
+
'options',
|
|
23
|
+
'infrastructure',
|
|
24
|
+
'features',
|
|
25
|
+
'datacenter',
|
|
26
|
+
], withProcessorPathValidation(withWorkerNameValidation(withQueueNameValidation(withVersionValidation(withOptionsValidation(withInfrastructureValidation(withFeaturesValidation(withDatacenterValidation(handler)))))))));
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Composite middleware for worker update validation
|
|
30
|
+
* Validates optional fields for updating an existing worker
|
|
31
|
+
*/
|
|
32
|
+
export const withUpdateWorkerValidation = (handler) => {
|
|
33
|
+
return withVersionValidation(withInfrastructureValidation(withFeaturesValidation(withDatacenterValidation(handler))));
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Composite middleware for worker operation validation
|
|
37
|
+
* Validates worker name for operations like start, stop, restart, etc.
|
|
38
|
+
*/
|
|
39
|
+
export const withWorkerOperationValidation = (handler) => {
|
|
40
|
+
return withWorkerNameValidation(handler);
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Composite middleware for bulk operations validation
|
|
44
|
+
* Validates arrays of worker names and operation parameters
|
|
45
|
+
*/
|
|
46
|
+
export const withBulkOperationValidation = (handler) => {
|
|
47
|
+
return async (req, res) => {
|
|
48
|
+
try {
|
|
49
|
+
const data = req.data();
|
|
50
|
+
const workerNames = data['workerNames'];
|
|
51
|
+
// Handle single worker name or array of names
|
|
52
|
+
const names = Array.isArray(workerNames) ? workerNames : [workerNames];
|
|
53
|
+
// Prevent enormous bulk operations
|
|
54
|
+
const MAX_BULK_NAMES = 1000;
|
|
55
|
+
if (names.length > MAX_BULK_NAMES) {
|
|
56
|
+
return res.setStatus(413).json({
|
|
57
|
+
error: 'Too many worker names',
|
|
58
|
+
message: `Bulk operation exceeds maximum allowed names (${MAX_BULK_NAMES})`,
|
|
59
|
+
code: 'BULK_OPERATION_TOO_LARGE',
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
if (!names || names.length === 0) {
|
|
63
|
+
return res.setStatus(400).json({
|
|
64
|
+
error: 'Worker names are required',
|
|
65
|
+
message: 'At least one worker name must be provided',
|
|
66
|
+
code: 'MISSING_WORKER_NAMES',
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
// Validate each worker name
|
|
70
|
+
const WORKER_NAME_PATTERN = /^[a-zA-Z0-9_-]{3,50}$/;
|
|
71
|
+
for (const name of names) {
|
|
72
|
+
if (!name || typeof name !== 'string') {
|
|
73
|
+
return res.setStatus(400).json({
|
|
74
|
+
error: 'Invalid worker name',
|
|
75
|
+
message: 'Worker name must be a string',
|
|
76
|
+
code: 'INVALID_WORKER_NAME_TYPE',
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (!WORKER_NAME_PATTERN.test(name)) {
|
|
80
|
+
return res.setStatus(400).json({
|
|
81
|
+
error: 'Invalid worker name',
|
|
82
|
+
message: `Worker name "${name}" must be 3-50 characters long and contain only letters, numbers, hyphens, and underscores`,
|
|
83
|
+
code: 'INVALID_WORKER_NAME',
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Sanitize worker names
|
|
88
|
+
const sanitizedNames = names
|
|
89
|
+
.map((name) => name
|
|
90
|
+
.trim()
|
|
91
|
+
.replaceAll(/[^a-zA-Z0-9_-]/g, '')
|
|
92
|
+
.substring(0, 50))
|
|
93
|
+
.filter((name) => name.length >= 3);
|
|
94
|
+
if (sanitizedNames.length === 0) {
|
|
95
|
+
return res.setStatus(400).json({
|
|
96
|
+
error: 'No valid worker names after sanitization',
|
|
97
|
+
message: 'All worker names were invalid after sanitization',
|
|
98
|
+
code: 'NO_VALID_WORKER_NAMES',
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
// Update request data with sanitized names
|
|
102
|
+
const currentBody = req.getBody();
|
|
103
|
+
req.setBody({ ...currentBody, workerNames: sanitizedNames });
|
|
104
|
+
return handler(req, res);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
Logger.error('Bulk operation validation failed', error);
|
|
108
|
+
return res.setStatus(500).json({
|
|
109
|
+
error: 'Internal validation error',
|
|
110
|
+
code: 'VALIDATION_ERROR',
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Composite middleware for canary deployment validation
|
|
117
|
+
* Validates canary-specific parameters
|
|
118
|
+
*/
|
|
119
|
+
export const withCanaryDeploymentValidation = (handler) => {
|
|
120
|
+
return async (req, res) => {
|
|
121
|
+
try {
|
|
122
|
+
const data = req.data();
|
|
123
|
+
const newVersion = data['newVersion'];
|
|
124
|
+
const initialTrafficPercent = data['initialTrafficPercent'];
|
|
125
|
+
const targetTrafficPercent = data['targetTrafficPercent'];
|
|
126
|
+
// Validate new version
|
|
127
|
+
if (!newVersion) {
|
|
128
|
+
return res.setStatus(400).json({
|
|
129
|
+
error: 'New version is required',
|
|
130
|
+
code: 'MISSING_NEW_VERSION',
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
const VERSION_PATTERN = /^\d+\.\d+\.\d+$/;
|
|
134
|
+
if (!VERSION_PATTERN.test(newVersion)) {
|
|
135
|
+
return res.setStatus(400).json({
|
|
136
|
+
error: 'Invalid version format',
|
|
137
|
+
message: 'Version must follow semantic versioning (e.g., 1.0.0)',
|
|
138
|
+
code: 'INVALID_VERSION_FORMAT',
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
// Validate initial traffic percent
|
|
142
|
+
if (initialTrafficPercent !== undefined) {
|
|
143
|
+
if (typeof initialTrafficPercent !== 'number' ||
|
|
144
|
+
initialTrafficPercent < 0 ||
|
|
145
|
+
initialTrafficPercent > 100) {
|
|
146
|
+
return res.setStatus(400).json({
|
|
147
|
+
error: 'Invalid initial traffic percent',
|
|
148
|
+
message: 'Initial traffic percent must be a number between 0 and 100',
|
|
149
|
+
code: 'INVALID_INITIAL_TRAFFIC_PERCENT',
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// Validate target traffic percent
|
|
154
|
+
if (targetTrafficPercent !== undefined) {
|
|
155
|
+
if (typeof targetTrafficPercent !== 'number' ||
|
|
156
|
+
targetTrafficPercent < 0 ||
|
|
157
|
+
targetTrafficPercent > 100) {
|
|
158
|
+
return res.setStatus(400).json({
|
|
159
|
+
error: 'Invalid target traffic percent',
|
|
160
|
+
message: 'Target traffic percent must be a number between 0 and 100',
|
|
161
|
+
code: 'INVALID_TARGET_TRAFFIC_PERCENT',
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Validate traffic progression
|
|
166
|
+
if (initialTrafficPercent !== undefined && targetTrafficPercent !== undefined) {
|
|
167
|
+
if (targetTrafficPercent < initialTrafficPercent) {
|
|
168
|
+
return res.setStatus(400).json({
|
|
169
|
+
error: 'Invalid traffic progression',
|
|
170
|
+
message: 'Target traffic percent must be greater than or equal to initial traffic percent',
|
|
171
|
+
code: 'INVALID_TRAFFIC_PROGRESSION',
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return handler(req, res);
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
Logger.error('Canary deployment validation failed', error);
|
|
179
|
+
return res.setStatus(500).json({
|
|
180
|
+
error: 'Internal validation error',
|
|
181
|
+
code: 'VALIDATION_ERROR',
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker Management System - Public API
|
|
3
|
+
*
|
|
4
|
+
* Central export file for all worker management modules.
|
|
5
|
+
*/
|
|
6
|
+
export { ClusterLock } from './ClusterLock';
|
|
7
|
+
export { PriorityQueue } from './PriorityQueue';
|
|
8
|
+
export { WorkerMetrics } from './WorkerMetrics';
|
|
9
|
+
export { WorkerRegistry } from './WorkerRegistry';
|
|
10
|
+
export { AutoScaler } from './AutoScaler';
|
|
11
|
+
export { CircuitBreaker } from './CircuitBreaker';
|
|
12
|
+
export { DeadLetterQueue } from './DeadLetterQueue';
|
|
13
|
+
export { HealthMonitor } from './HealthMonitor';
|
|
14
|
+
export { ResourceMonitor } from './ResourceMonitor';
|
|
15
|
+
export { SLAMonitor } from './SLAMonitor';
|
|
16
|
+
export { ComplianceManager } from './ComplianceManager';
|
|
17
|
+
export { Observability } from './Observability';
|
|
18
|
+
export { PluginManager } from './PluginManager';
|
|
19
|
+
export { AnomalyDetection } from './AnomalyDetection';
|
|
20
|
+
export { CanaryController } from './CanaryController';
|
|
21
|
+
export { ChaosEngineering } from './ChaosEngineering';
|
|
22
|
+
export { DatacenterOrchestrator } from './DatacenterOrchestrator';
|
|
23
|
+
export { MultiQueueWorker } from './MultiQueueWorker';
|
|
24
|
+
export { WorkerVersioning } from './WorkerVersioning';
|
|
25
|
+
export { WorkerFactory } from './WorkerFactory';
|
|
26
|
+
export type { WorkerPersistenceConfig } from './WorkerFactory';
|
|
27
|
+
export { WorkerInit } from './WorkerInit';
|
|
28
|
+
export { WorkerShutdown } from './WorkerShutdown';
|
|
29
|
+
export { WorkerController } from './http/WorkerController';
|
|
30
|
+
export { registerWorkerRoutes } from './routes/workers';
|
|
31
|
+
export { BroadcastWorker } from './BroadcastWorker';
|
|
32
|
+
export { createQueueWorker } from './createQueueWorker';
|
|
33
|
+
export type { CreateQueueWorkerOptions } from './createQueueWorker';
|
|
34
|
+
export { NotificationWorker } from './NotificationWorker';
|
|
35
|
+
export type { RedisConfig, WorkerAutoScalingConfig, WorkerComplianceConfig, WorkerConfig, WorkerCostConfig, WorkerObservabilityConfig, WorkersConfigOverrides, WorkersGlobalConfig, WorkerStatus, WorkerVersioningConfig, } from '@zintrust/core';
|
|
36
|
+
export type { Job, Worker, WorkerOptions } from 'bullmq';
|
|
37
|
+
export type { IAnomaly, IAnomalyConfig, IForecast, IMetric, IPrediction, IRecommendation, IRootCauseAnalysis, } from './AnomalyDetection';
|
|
38
|
+
export type { IChaosComparison, IChaosExperiment, IChaosReport, IChaosStatus, } from './ChaosEngineering';
|
|
39
|
+
export type { ISLAConfig, ISLAReport, ISLAStatus, ISLAViolation, ITimeRange } from './SLAMonitor';
|
|
40
|
+
export type * from './type';
|
|
41
|
+
/**
|
|
42
|
+
* Package version and build metadata
|
|
43
|
+
* Available at runtime for debugging and health checks
|
|
44
|
+
*/
|
|
45
|
+
export declare const _ZINTRUST_WORKERS_VERSION = "0.1.0";
|
|
46
|
+
export declare const _ZINTRUST_WORKERS_BUILD_DATE = "__BUILD_DATE__";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker Management System - Public API
|
|
3
|
+
*
|
|
4
|
+
* Central export file for all worker management modules.
|
|
5
|
+
*/
|
|
6
|
+
// Core Infrastructure
|
|
7
|
+
export { ClusterLock } from './ClusterLock';
|
|
8
|
+
export { PriorityQueue } from './PriorityQueue';
|
|
9
|
+
export { WorkerMetrics } from './WorkerMetrics';
|
|
10
|
+
export { WorkerRegistry } from './WorkerRegistry';
|
|
11
|
+
// Resilience & Recovery
|
|
12
|
+
export { AutoScaler } from './AutoScaler';
|
|
13
|
+
export { CircuitBreaker } from './CircuitBreaker';
|
|
14
|
+
export { DeadLetterQueue } from './DeadLetterQueue';
|
|
15
|
+
// Monitoring & Resources
|
|
16
|
+
export { HealthMonitor } from './HealthMonitor';
|
|
17
|
+
export { ResourceMonitor } from './ResourceMonitor';
|
|
18
|
+
export { SLAMonitor } from './SLAMonitor';
|
|
19
|
+
// Compliance & Security
|
|
20
|
+
export { ComplianceManager } from './ComplianceManager';
|
|
21
|
+
// Observability
|
|
22
|
+
export { Observability } from './Observability';
|
|
23
|
+
// Plugin System
|
|
24
|
+
export { PluginManager } from './PluginManager';
|
|
25
|
+
// Advanced Features
|
|
26
|
+
export { AnomalyDetection } from './AnomalyDetection';
|
|
27
|
+
export { CanaryController } from './CanaryController';
|
|
28
|
+
export { ChaosEngineering } from './ChaosEngineering';
|
|
29
|
+
export { DatacenterOrchestrator } from './DatacenterOrchestrator';
|
|
30
|
+
export { MultiQueueWorker } from './MultiQueueWorker';
|
|
31
|
+
export { WorkerVersioning } from './WorkerVersioning';
|
|
32
|
+
// Factory & Lifecycle
|
|
33
|
+
export { WorkerFactory } from './WorkerFactory';
|
|
34
|
+
export { WorkerInit } from './WorkerInit';
|
|
35
|
+
export { WorkerShutdown } from './WorkerShutdown';
|
|
36
|
+
// HTTP Controllers & Routes
|
|
37
|
+
export { WorkerController } from './http/WorkerController';
|
|
38
|
+
export { registerWorkerRoutes } from './routes/workers';
|
|
39
|
+
// Queue Workers
|
|
40
|
+
export { BroadcastWorker } from './BroadcastWorker';
|
|
41
|
+
export { createQueueWorker } from './createQueueWorker';
|
|
42
|
+
export { NotificationWorker } from './NotificationWorker';
|
|
43
|
+
/**
|
|
44
|
+
* Package version and build metadata
|
|
45
|
+
* Available at runtime for debugging and health checks
|
|
46
|
+
*/
|
|
47
|
+
export const _ZINTRUST_WORKERS_VERSION = '0.1.0';
|
|
48
|
+
export const _ZINTRUST_WORKERS_BUILD_DATE = '__BUILD_DATE__';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker Management Routes
|
|
3
|
+
* HTTP API for managing workers with dashboard functionality
|
|
4
|
+
*/
|
|
5
|
+
import type { IRouter } from '@zintrust/core';
|
|
6
|
+
import { type WorkersDashboardUiOptions } from '../dashboard';
|
|
7
|
+
type WorkerUiOptions = WorkersDashboardUiOptions;
|
|
8
|
+
type RouteOptions = {
|
|
9
|
+
middleware?: ReadonlyArray<string>;
|
|
10
|
+
} | undefined;
|
|
11
|
+
export declare function registerWorkerRoutes(router: IRouter, _options?: WorkerUiOptions, routeOptions?: RouteOptions): void;
|
|
12
|
+
export default registerWorkerRoutes;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker Management Routes
|
|
3
|
+
* HTTP API for managing workers with dashboard functionality
|
|
4
|
+
*/
|
|
5
|
+
import { Logger, Router } from '@zintrust/core';
|
|
6
|
+
import { WorkerApiController } from '../http/WorkerApiController';
|
|
7
|
+
import { WorkerController } from '../http/WorkerController';
|
|
8
|
+
import { ValidationSchemas, withCustomValidation } from '../http/middleware/CustomValidation';
|
|
9
|
+
import { withEditWorkerValidation } from '../http/middleware/EditWorkerValidation';
|
|
10
|
+
import { withDriverValidation } from '../http/middleware/ValidateDriver';
|
|
11
|
+
import { withCreateWorkerValidation, withWorkerOperationValidation, } from '../http/middleware/WorkerValidationChain';
|
|
12
|
+
import { registerStaticAssets } from '../ui/router/ui';
|
|
13
|
+
const controller = WorkerController.create();
|
|
14
|
+
const apiController = WorkerApiController.create();
|
|
15
|
+
function registerCoreWorkerRoutes(r) {
|
|
16
|
+
// Core worker operations
|
|
17
|
+
Router.post(r, '/create', withCreateWorkerValidation(controller.create));
|
|
18
|
+
Router.put(r, '/:name', withCreateWorkerValidation(controller.update));
|
|
19
|
+
// Worker editing with custom validation that handles processorPath mapping
|
|
20
|
+
Router.put(r, '/:name/edit', withEditWorkerValidation(controller.update));
|
|
21
|
+
Router.post(r, '/:name/start', withDriverValidation(withWorkerOperationValidation(controller.start)));
|
|
22
|
+
Router.post(r, '/:name/auto-start', withDriverValidation(withWorkerOperationValidation(controller.setAutoStart)));
|
|
23
|
+
Router.post(r, '/:name/stop', withDriverValidation(withWorkerOperationValidation(controller.stop)));
|
|
24
|
+
Router.post(r, '/:name/restart', withDriverValidation(withWorkerOperationValidation(controller.restart)));
|
|
25
|
+
Router.post(r, '/:name/pause', withDriverValidation(withWorkerOperationValidation(controller.pause)));
|
|
26
|
+
Router.post(r, '/:name/resume', withDriverValidation(withWorkerOperationValidation(controller.resume)));
|
|
27
|
+
Router.del(r, '/:name', withDriverValidation(withWorkerOperationValidation(controller.remove)));
|
|
28
|
+
}
|
|
29
|
+
function registerWorkerQueryRoutes(r) {
|
|
30
|
+
// Worker listing and filtering
|
|
31
|
+
Router.get(r, '/', withDriverValidation(withCustomValidation(ValidationSchemas.workerFilter, apiController.listWorkers)));
|
|
32
|
+
Router.get(r, '/:name', withDriverValidation(withWorkerOperationValidation(controller.get)));
|
|
33
|
+
Router.get(r, '/:name/status', withWorkerOperationValidation(controller.status));
|
|
34
|
+
Router.get(r, '/:name/creation-status', withWorkerOperationValidation(controller.getCreationStatus));
|
|
35
|
+
Router.get(r, '/:name/metrics', withWorkerOperationValidation(controller.metrics));
|
|
36
|
+
Router.get(r, '/:name/health', withWorkerOperationValidation(controller.health));
|
|
37
|
+
// Worker details
|
|
38
|
+
Router.get(r, '/:name/details', withDriverValidation(apiController.getWorkerDetailsHandler));
|
|
39
|
+
// Worker driver data for editing
|
|
40
|
+
Router.get(r, '/:name/driver-data', withDriverValidation(apiController.getWorkerDriverDataHandler));
|
|
41
|
+
}
|
|
42
|
+
function registerMonitoringRoutes(r) {
|
|
43
|
+
// Health monitoring
|
|
44
|
+
Router.post(r, '/:name/monitoring/start', controller.startMonitoring);
|
|
45
|
+
Router.post(r, '/:name/monitoring/stop', controller.stopMonitoring);
|
|
46
|
+
Router.get(r, '/:name/monitoring/history', controller.healthHistory);
|
|
47
|
+
Router.get(r, '/:name/monitoring/trend', controller.healthTrend);
|
|
48
|
+
Router.put(r, '/:name/monitoring/config', controller.updateMonitoringConfig);
|
|
49
|
+
// SLA monitoring
|
|
50
|
+
Router.get(r, '/:name/sla/status', controller.getSlaStatus);
|
|
51
|
+
// SSE events stream for monitoring + workers snapshot
|
|
52
|
+
Router.get(r, '/events', controller.eventsStream);
|
|
53
|
+
}
|
|
54
|
+
function registerVersioningRoutes(r) {
|
|
55
|
+
// Versioning
|
|
56
|
+
Router.post(r, '/:name/versions', controller.registerVersion);
|
|
57
|
+
Router.get(r, '/:name/versions', controller.listVersions);
|
|
58
|
+
Router.get(r, '/:name/versions/:version', controller.getVersion);
|
|
59
|
+
}
|
|
60
|
+
function registerUtilityRoutes(r) {
|
|
61
|
+
// Utility endpoints
|
|
62
|
+
Router.get(r, '/drivers', apiController.getDriversHandler);
|
|
63
|
+
Router.get(r, '/queue-data', apiController.getQueueDataHandler);
|
|
64
|
+
Router.get(r, '/health', apiController.getHealthSummaryHandler);
|
|
65
|
+
}
|
|
66
|
+
function registerWorkerLifecycleRoutes(router, middleware) {
|
|
67
|
+
Router.group(router, '/api/workers', (r) => {
|
|
68
|
+
Logger.info('Registering Worker Management Routes');
|
|
69
|
+
registerCoreWorkerRoutes(r);
|
|
70
|
+
registerWorkerQueryRoutes(r);
|
|
71
|
+
registerMonitoringRoutes(r);
|
|
72
|
+
registerVersioningRoutes(r);
|
|
73
|
+
registerUtilityRoutes(r);
|
|
74
|
+
}, { middleware: middleware });
|
|
75
|
+
}
|
|
76
|
+
export function registerWorkerRoutes(router, _options, routeOptions) {
|
|
77
|
+
registerStaticAssets(router, routeOptions?.middleware ?? []);
|
|
78
|
+
registerWorkerLifecycleRoutes(router, routeOptions?.middleware);
|
|
79
|
+
Logger.info('Worker routes registered at http://127.0.0.1:7777/workers');
|
|
80
|
+
}
|
|
81
|
+
export default registerWorkerRoutes;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker Store
|
|
3
|
+
* Persistence layer for workers (memory, redis, db)
|
|
4
|
+
*/
|
|
5
|
+
import type { IDatabase } from '@zintrust/core';
|
|
6
|
+
import type { Redis } from 'ioredis';
|
|
7
|
+
export type WorkerRecord = {
|
|
8
|
+
name: string;
|
|
9
|
+
queueName: string;
|
|
10
|
+
version: string | null;
|
|
11
|
+
status: string;
|
|
12
|
+
autoStart: boolean;
|
|
13
|
+
concurrency: number;
|
|
14
|
+
region: string | null;
|
|
15
|
+
processorPath?: string | null;
|
|
16
|
+
features?: Record<string, unknown> | null;
|
|
17
|
+
infrastructure?: Record<string, unknown> | null;
|
|
18
|
+
datacenter?: Record<string, unknown> | null;
|
|
19
|
+
createdAt: Date;
|
|
20
|
+
updatedAt: Date;
|
|
21
|
+
lastHealthCheck?: Date;
|
|
22
|
+
lastError?: string;
|
|
23
|
+
connectionState?: 'disconnected' | 'connecting' | 'connected' | 'error';
|
|
24
|
+
};
|
|
25
|
+
export type WorkerStore = {
|
|
26
|
+
init(): Promise<void>;
|
|
27
|
+
list(options?: {
|
|
28
|
+
offset?: number;
|
|
29
|
+
limit?: number;
|
|
30
|
+
search?: string;
|
|
31
|
+
}): Promise<WorkerRecord[]>;
|
|
32
|
+
get(name: string): Promise<WorkerRecord | null>;
|
|
33
|
+
save(record: WorkerRecord): Promise<void>;
|
|
34
|
+
update(name: string, patch: Partial<WorkerRecord>): Promise<void>;
|
|
35
|
+
remove(name: string): Promise<void>;
|
|
36
|
+
};
|
|
37
|
+
export declare const InMemoryWorkerStore: Readonly<{
|
|
38
|
+
create(): WorkerStore;
|
|
39
|
+
}>;
|
|
40
|
+
export declare const RedisWorkerStore: Readonly<{
|
|
41
|
+
create(client: Redis, keyPrefix?: string): WorkerStore;
|
|
42
|
+
}>;
|
|
43
|
+
export declare const DbWorkerStore: Readonly<{
|
|
44
|
+
create(db: IDatabase, table?: string): WorkerStore;
|
|
45
|
+
}>;
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker Store
|
|
3
|
+
* Persistence layer for workers (memory, redis, db)
|
|
4
|
+
*/
|
|
5
|
+
const now = () => new Date();
|
|
6
|
+
const mergeRecord = (current, patch) => ({
|
|
7
|
+
...current,
|
|
8
|
+
...patch,
|
|
9
|
+
updatedAt: patch.updatedAt ?? now(),
|
|
10
|
+
});
|
|
11
|
+
const serializeDbWorker = (record) => ({
|
|
12
|
+
name: record.name,
|
|
13
|
+
queue_name: record.queueName,
|
|
14
|
+
version: record.version,
|
|
15
|
+
status: record.status,
|
|
16
|
+
auto_start: record.autoStart,
|
|
17
|
+
concurrency: record.concurrency,
|
|
18
|
+
region: record.region,
|
|
19
|
+
processor_path: record.processorPath ?? null,
|
|
20
|
+
features: record.features ? JSON.stringify(record.features) : null,
|
|
21
|
+
infrastructure: record.infrastructure ? JSON.stringify(record.infrastructure) : null,
|
|
22
|
+
datacenter: record.datacenter ? JSON.stringify(record.datacenter) : null,
|
|
23
|
+
created_at: record.createdAt,
|
|
24
|
+
updated_at: record.updatedAt,
|
|
25
|
+
last_health_check: record.lastHealthCheck ?? null,
|
|
26
|
+
last_error: record.lastError ?? null,
|
|
27
|
+
connection_state: record.connectionState ?? null,
|
|
28
|
+
});
|
|
29
|
+
const getHealthCheck = (row) => {
|
|
30
|
+
if (!row['last_health_check']) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
return row['last_health_check'] instanceof Date
|
|
34
|
+
? row['last_health_check']
|
|
35
|
+
: new Date(String(row['last_health_check']));
|
|
36
|
+
};
|
|
37
|
+
const deserializeDbWorker = (row) => {
|
|
38
|
+
const parseJson = (value) => {
|
|
39
|
+
if (typeof value !== 'string' || value.trim() === '')
|
|
40
|
+
return null;
|
|
41
|
+
try {
|
|
42
|
+
return JSON.parse(value);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
return {
|
|
49
|
+
name: String(row['name'] ?? ''),
|
|
50
|
+
queueName: String(row['queue_name'] ?? ''),
|
|
51
|
+
version: row['version'] ? String(row['version']) : null,
|
|
52
|
+
status: String(row['status'] ?? 'unknown'),
|
|
53
|
+
autoStart: Boolean(row['auto_start'] ?? false),
|
|
54
|
+
concurrency: Number(row['concurrency'] ?? 0),
|
|
55
|
+
region: row['region'] ? String(row['region']) : null,
|
|
56
|
+
processorPath: row['processor_path'] ? String(row['processor_path']) : null,
|
|
57
|
+
features: parseJson(row['features']),
|
|
58
|
+
infrastructure: parseJson(row['infrastructure']),
|
|
59
|
+
datacenter: parseJson(row['datacenter']),
|
|
60
|
+
createdAt: row['created_at'] instanceof Date ? row['created_at'] : new Date(String(row['created_at'])),
|
|
61
|
+
updatedAt: row['updated_at'] instanceof Date ? row['updated_at'] : new Date(String(row['updated_at'])),
|
|
62
|
+
lastHealthCheck: getHealthCheck(row),
|
|
63
|
+
lastError: row['last_error'] ? String(row['last_error']) : undefined,
|
|
64
|
+
connectionState: row['connection_state']
|
|
65
|
+
? String(row['connection_state'])
|
|
66
|
+
: undefined,
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
export const InMemoryWorkerStore = Object.freeze({
|
|
70
|
+
create() {
|
|
71
|
+
const store = new Map();
|
|
72
|
+
return {
|
|
73
|
+
async init() {
|
|
74
|
+
return undefined;
|
|
75
|
+
},
|
|
76
|
+
async list(options) {
|
|
77
|
+
let values = Array.from(store.values());
|
|
78
|
+
if (options) {
|
|
79
|
+
const start = options.offset || 0;
|
|
80
|
+
const end = options.limit ? start + options.limit : undefined;
|
|
81
|
+
values = values.slice(start, end);
|
|
82
|
+
}
|
|
83
|
+
return values;
|
|
84
|
+
},
|
|
85
|
+
async get(name) {
|
|
86
|
+
return store.get(name) ?? null;
|
|
87
|
+
},
|
|
88
|
+
async save(record) {
|
|
89
|
+
store.set(record.name, record);
|
|
90
|
+
},
|
|
91
|
+
async update(name, patch) {
|
|
92
|
+
const current = store.get(name);
|
|
93
|
+
if (!current)
|
|
94
|
+
return;
|
|
95
|
+
store.set(name, mergeRecord(current, patch));
|
|
96
|
+
},
|
|
97
|
+
async remove(name) {
|
|
98
|
+
store.delete(name);
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
export const RedisWorkerStore = Object.freeze({
|
|
104
|
+
create(client, keyPrefix = 'workers:registry') {
|
|
105
|
+
const key = keyPrefix;
|
|
106
|
+
const serialize = (record) => JSON.stringify({
|
|
107
|
+
...record,
|
|
108
|
+
createdAt: record.createdAt.toISOString(),
|
|
109
|
+
updatedAt: record.updatedAt.toISOString(),
|
|
110
|
+
});
|
|
111
|
+
const deserialize = (raw) => {
|
|
112
|
+
const parsed = JSON.parse(raw);
|
|
113
|
+
return {
|
|
114
|
+
...parsed,
|
|
115
|
+
createdAt: new Date(parsed.createdAt),
|
|
116
|
+
updatedAt: new Date(parsed.updatedAt),
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
return {
|
|
120
|
+
async init() {
|
|
121
|
+
return undefined;
|
|
122
|
+
},
|
|
123
|
+
async list(options) {
|
|
124
|
+
const all = await client.hgetall(key);
|
|
125
|
+
let values = Object.values(all).map(deserialize);
|
|
126
|
+
values.sort((a, b) => a.name.localeCompare(b.name));
|
|
127
|
+
if (options) {
|
|
128
|
+
const start = options.offset || 0;
|
|
129
|
+
const end = options.limit ? start + options.limit : undefined;
|
|
130
|
+
values = values.slice(start, end);
|
|
131
|
+
}
|
|
132
|
+
return values;
|
|
133
|
+
},
|
|
134
|
+
async get(name) {
|
|
135
|
+
const raw = await client.hget(key, name);
|
|
136
|
+
return raw ? deserialize(raw) : null;
|
|
137
|
+
},
|
|
138
|
+
async save(record) {
|
|
139
|
+
await client.hset(key, record.name, serialize(record));
|
|
140
|
+
},
|
|
141
|
+
async update(name, patch) {
|
|
142
|
+
const current = await this.get(name);
|
|
143
|
+
if (!current)
|
|
144
|
+
return;
|
|
145
|
+
await client.hset(key, name, serialize(mergeRecord(current, patch)));
|
|
146
|
+
},
|
|
147
|
+
async remove(name) {
|
|
148
|
+
await client.hdel(key, name);
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
export const DbWorkerStore = Object.freeze({
|
|
154
|
+
create(db, table = 'zintrust_workers') {
|
|
155
|
+
return {
|
|
156
|
+
async init() {
|
|
157
|
+
return undefined;
|
|
158
|
+
},
|
|
159
|
+
async list(options) {
|
|
160
|
+
const query = db.table(table);
|
|
161
|
+
if (options?.limit)
|
|
162
|
+
query.limit(options.limit);
|
|
163
|
+
if (options?.offset)
|
|
164
|
+
query.offset(options.offset);
|
|
165
|
+
const rows = await query.get();
|
|
166
|
+
return rows.map(deserializeDbWorker);
|
|
167
|
+
},
|
|
168
|
+
async get(name) {
|
|
169
|
+
const row = await db.table(table).where('name', '=', name).first();
|
|
170
|
+
return row ? deserializeDbWorker(row) : null;
|
|
171
|
+
},
|
|
172
|
+
async save(record) {
|
|
173
|
+
const existing = await db
|
|
174
|
+
.table(table)
|
|
175
|
+
.where('name', '=', record.name)
|
|
176
|
+
.first();
|
|
177
|
+
if (existing) {
|
|
178
|
+
await db.table(table).where('name', '=', record.name).update(serializeDbWorker(record));
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
await db.table(table).insert(serializeDbWorker(record));
|
|
182
|
+
},
|
|
183
|
+
async update(name, patch) {
|
|
184
|
+
const current = await this.get(name);
|
|
185
|
+
if (!current)
|
|
186
|
+
return;
|
|
187
|
+
const updated = mergeRecord(current, patch);
|
|
188
|
+
await db.table(table).where('name', '=', name).update(serializeDbWorker(updated));
|
|
189
|
+
},
|
|
190
|
+
async remove(name) {
|
|
191
|
+
await db.table(table).where('name', '=', name).delete();
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
},
|
|
195
|
+
});
|