bootifyjs 1.2.0 → 1.2.1
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 +1 -1
- package/dist/api.d.ts +1 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +1 -0
- package/dist/api.js.map +1 -1
- package/dist/auth/examples/basic-usage.d.ts +2 -1
- package/dist/auth/examples/basic-usage.d.ts.map +1 -1
- package/dist/auth/examples/basic-usage.js +3 -2
- package/dist/auth/examples/basic-usage.js.map +1 -1
- package/dist/auth/index.d.ts +6 -8
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +11 -11
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/middleware/AuthMiddleware.js.map +1 -1
- package/dist/cache/bootstrap.js +1 -1
- package/dist/cache/bootstrap.js.map +1 -1
- package/dist/cache/index.d.ts +2 -1
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +4 -1
- package/dist/cache/index.js.map +1 -1
- package/dist/cache/{in-memory-cache.store.d.ts → stores/in-memory-cache.store.d.ts} +1 -1
- package/dist/cache/stores/in-memory-cache.store.d.ts.map +1 -0
- package/dist/cache/{in-memory-cache.store.js → stores/in-memory-cache.store.js} +1 -1
- package/dist/cache/stores/in-memory-cache.store.js.map +1 -0
- package/dist/cache/stores/index.d.ts +3 -0
- package/dist/cache/stores/index.d.ts.map +1 -0
- package/dist/cache/stores/index.js +20 -0
- package/dist/cache/stores/index.js.map +1 -0
- package/dist/cache/stores/redis-cache.store.d.ts +8 -0
- package/dist/cache/stores/redis-cache.store.d.ts.map +1 -0
- package/dist/cache/stores/redis-cache.store.js +39 -0
- package/dist/cache/stores/redis-cache.store.js.map +1 -0
- package/dist/core/router.d.ts.map +1 -1
- package/dist/core/router.js +3 -3
- package/dist/core/router.js.map +1 -1
- package/dist/events/bootstrap.d.ts +13 -1
- package/dist/events/bootstrap.d.ts.map +1 -1
- package/dist/events/bootstrap.js +30 -2
- package/dist/events/bootstrap.js.map +1 -1
- package/dist/events/buffered-event-bus.service.d.ts +135 -0
- package/dist/events/buffered-event-bus.service.d.ts.map +1 -0
- package/dist/events/buffered-event-bus.service.js +420 -0
- package/dist/events/buffered-event-bus.service.js.map +1 -0
- package/dist/events/config/buffered-event-config.d.ts +153 -0
- package/dist/events/config/buffered-event-config.d.ts.map +1 -0
- package/dist/events/config/buffered-event-config.js +181 -0
- package/dist/events/config/buffered-event-config.js.map +1 -0
- package/dist/events/index.d.ts +3 -0
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +3 -0
- package/dist/events/index.js.map +1 -1
- package/dist/events/metrics/event-metrics.d.ts +175 -0
- package/dist/events/metrics/event-metrics.d.ts.map +1 -0
- package/dist/events/metrics/event-metrics.js +235 -0
- package/dist/events/metrics/event-metrics.js.map +1 -0
- package/dist/events/monitoring/health-monitor.d.ts +142 -0
- package/dist/events/monitoring/health-monitor.d.ts.map +1 -0
- package/dist/events/monitoring/health-monitor.js +492 -0
- package/dist/events/monitoring/health-monitor.js.map +1 -0
- package/dist/events/retry/retry-handler.d.ts +112 -0
- package/dist/events/retry/retry-handler.d.ts.map +1 -0
- package/dist/events/retry/retry-handler.js +218 -0
- package/dist/events/retry/retry-handler.js.map +1 -0
- package/dist/events/shared-buffer.d.ts +92 -0
- package/dist/events/shared-buffer.d.ts.map +1 -0
- package/dist/events/shared-buffer.js +179 -0
- package/dist/events/shared-buffer.js.map +1 -0
- package/dist/events/worker/event-processor.worker.d.ts +75 -0
- package/dist/events/worker/event-processor.worker.d.ts.map +1 -0
- package/dist/events/worker/event-processor.worker.js +293 -0
- package/dist/events/worker/event-processor.worker.js.map +1 -0
- package/dist/events/worker/worker-manager.d.ts +132 -0
- package/dist/events/worker/worker-manager.d.ts.map +1 -0
- package/dist/events/worker/worker-manager.js +436 -0
- package/dist/events/worker/worker-manager.js.map +1 -0
- package/dist/examples/auth/auth.middleware.d.ts +0 -26
- package/dist/examples/auth/auth.middleware.d.ts.map +1 -1
- package/dist/examples/auth/auth.middleware.js +0 -185
- package/dist/examples/auth/auth.middleware.js.map +1 -1
- package/dist/examples/controllers/auth.controller.d.ts +0 -63
- package/dist/examples/controllers/auth.controller.d.ts.map +1 -1
- package/dist/examples/controllers/auth.controller.js +247 -282
- package/dist/examples/controllers/auth.controller.js.map +1 -1
- package/dist/examples/events/buffered-event-example.d.ts +71 -0
- package/dist/examples/events/buffered-event-example.d.ts.map +1 -0
- package/dist/examples/events/buffered-event-example.js +182 -0
- package/dist/examples/events/buffered-event-example.js.map +1 -0
- package/dist/examples/events/integration-test.d.ts +10 -0
- package/dist/examples/events/integration-test.d.ts.map +1 -0
- package/dist/examples/events/integration-test.js +147 -0
- package/dist/examples/events/integration-test.js.map +1 -0
- package/dist/examples/index.d.ts +1 -0
- package/dist/examples/index.d.ts.map +1 -1
- package/dist/examples/index.js +9 -6
- package/dist/examples/index.js.map +1 -1
- package/dist/examples/todos/schema.d.ts +4 -4
- package/package.json +1 -1
- package/dist/cache/in-memory-cache.store.d.ts.map +0 -1
- package/dist/cache/in-memory-cache.store.js.map +0 -1
- package/dist/examples/authorization-examples.d.ts +0 -67
- package/dist/examples/authorization-examples.d.ts.map +0 -1
- package/dist/examples/authorization-examples.js +0 -202
- package/dist/examples/authorization-examples.js.map +0 -1
- package/dist/examples/controllers/todo-updated.controller.d.ts +0 -103
- package/dist/examples/controllers/todo-updated.controller.d.ts.map +0 -1
- package/dist/examples/controllers/todo-updated.controller.js +0 -328
- package/dist/examples/controllers/todo-updated.controller.js.map +0 -1
- package/dist/examples/controllers/todo-with-jwt-auth.controller.d.ts +0 -114
- package/dist/examples/controllers/todo-with-jwt-auth.controller.d.ts.map +0 -1
- package/dist/examples/controllers/todo-with-jwt-auth.controller.js +0 -329
- package/dist/examples/controllers/todo-with-jwt-auth.controller.js.map +0 -1
- package/dist/examples/jwt-auth-example.d.ts +0 -47
- package/dist/examples/jwt-auth-example.d.ts.map +0 -1
- package/dist/examples/jwt-auth-example.js +0 -316
- package/dist/examples/jwt-auth-example.js.map +0 -1
- package/dist/examples/services/user.service.d.ts +0 -99
- package/dist/examples/services/user.service.d.ts.map +0 -1
- package/dist/examples/services/user.service.js +0 -281
- package/dist/examples/services/user.service.js.map +0 -1
- package/dist/examples/test-auth-flow.d.ts +0 -56
- package/dist/examples/test-auth-flow.d.ts.map +0 -1
- package/dist/examples/test-auth-flow.js +0 -449
- package/dist/examples/test-auth-flow.js.map +0 -1
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.ManagedWorker = exports.WorkerManager = void 0;
|
|
37
|
+
const worker_threads_1 = require("worker_threads");
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const events_1 = require("events");
|
|
40
|
+
/**
|
|
41
|
+
* Worker thread wrapper with communication and lifecycle management
|
|
42
|
+
*/
|
|
43
|
+
class ManagedWorker extends events_1.EventEmitter {
|
|
44
|
+
constructor(id, workerScript, config, sharedBuffer) {
|
|
45
|
+
super();
|
|
46
|
+
this.status = 'idle';
|
|
47
|
+
this.lastActivity = Date.now();
|
|
48
|
+
this.eventsProcessed = 0;
|
|
49
|
+
this.errors = 0;
|
|
50
|
+
this.isShuttingDown = false;
|
|
51
|
+
this.startTime = Date.now();
|
|
52
|
+
this.id = id;
|
|
53
|
+
// Create worker thread with ts-node support
|
|
54
|
+
this.worker = new worker_threads_1.Worker(workerScript, {
|
|
55
|
+
workerData: { workerId: id },
|
|
56
|
+
execArgv: ['--require', 'ts-node/register']
|
|
57
|
+
});
|
|
58
|
+
this.setupWorkerCommunication();
|
|
59
|
+
this.initializeWorker(config, sharedBuffer);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Setup communication with worker thread
|
|
63
|
+
*/
|
|
64
|
+
setupWorkerCommunication() {
|
|
65
|
+
this.worker.on('message', (message) => {
|
|
66
|
+
this.handleWorkerMessage(message);
|
|
67
|
+
});
|
|
68
|
+
this.worker.on('error', (error) => {
|
|
69
|
+
console.error(`[Worker ${this.id}] Error:`, error);
|
|
70
|
+
this.status = 'error';
|
|
71
|
+
this.errors++;
|
|
72
|
+
this.emit('error', error);
|
|
73
|
+
});
|
|
74
|
+
this.worker.on('exit', (code) => {
|
|
75
|
+
console.log(`[Worker ${this.id}] Exited with code ${code}`);
|
|
76
|
+
this.status = 'idle';
|
|
77
|
+
this.emit('exit', code);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Handle messages from worker thread
|
|
82
|
+
*/
|
|
83
|
+
handleWorkerMessage(message) {
|
|
84
|
+
switch (message.type) {
|
|
85
|
+
case 'ready':
|
|
86
|
+
this.status = 'running';
|
|
87
|
+
this.emit('ready');
|
|
88
|
+
break;
|
|
89
|
+
case 'event_processed':
|
|
90
|
+
this.eventsProcessed++;
|
|
91
|
+
this.lastActivity = Date.now();
|
|
92
|
+
this.emit('event_processed', message);
|
|
93
|
+
break;
|
|
94
|
+
case 'error':
|
|
95
|
+
this.errors++;
|
|
96
|
+
this.emit('worker_error', message.error, message.eventType);
|
|
97
|
+
break;
|
|
98
|
+
case 'health_status':
|
|
99
|
+
this.updateStatus(message.status);
|
|
100
|
+
this.emit('health_status', message.status);
|
|
101
|
+
break;
|
|
102
|
+
case 'stats':
|
|
103
|
+
this.emit('stats', message.stats);
|
|
104
|
+
break;
|
|
105
|
+
case 'shutdown_complete':
|
|
106
|
+
this.status = 'idle';
|
|
107
|
+
this.emit('shutdown_complete');
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Initialize worker with configuration
|
|
113
|
+
*/
|
|
114
|
+
initializeWorker(config, sharedBuffer) {
|
|
115
|
+
this.worker.postMessage({
|
|
116
|
+
type: 'init',
|
|
117
|
+
config,
|
|
118
|
+
sharedBuffer
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Register event handler in worker
|
|
123
|
+
*/
|
|
124
|
+
registerHandler(eventType, handler) {
|
|
125
|
+
// Convert handler to serializable code (simplified approach)
|
|
126
|
+
const handlerCode = handler.handle.toString();
|
|
127
|
+
this.worker.postMessage({
|
|
128
|
+
type: 'register_handler',
|
|
129
|
+
eventType,
|
|
130
|
+
handlerCode
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Update worker status
|
|
135
|
+
*/
|
|
136
|
+
updateStatus(status) {
|
|
137
|
+
this.status = status.status;
|
|
138
|
+
this.eventsProcessed = status.eventsProcessed;
|
|
139
|
+
this.lastActivity = status.lastActivity;
|
|
140
|
+
this.errors = status.errors;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Request health check from worker
|
|
144
|
+
*/
|
|
145
|
+
requestHealthCheck() {
|
|
146
|
+
this.worker.postMessage({ type: 'health_check' });
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Request statistics from worker
|
|
150
|
+
*/
|
|
151
|
+
requestStats() {
|
|
152
|
+
this.worker.postMessage({ type: 'get_stats' });
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Shutdown worker gracefully
|
|
156
|
+
*/
|
|
157
|
+
async shutdown(timeout = 5000) {
|
|
158
|
+
if (this.isShuttingDown) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
this.isShuttingDown = true;
|
|
162
|
+
this.status = 'restarting';
|
|
163
|
+
return new Promise((resolve, reject) => {
|
|
164
|
+
const shutdownTimeout = setTimeout(() => {
|
|
165
|
+
console.warn(`[Worker ${this.id}] Shutdown timeout, terminating forcefully`);
|
|
166
|
+
this.worker.terminate();
|
|
167
|
+
reject(new Error('Shutdown timeout'));
|
|
168
|
+
}, timeout);
|
|
169
|
+
this.once('shutdown_complete', () => {
|
|
170
|
+
clearTimeout(shutdownTimeout);
|
|
171
|
+
resolve();
|
|
172
|
+
});
|
|
173
|
+
this.once('exit', () => {
|
|
174
|
+
clearTimeout(shutdownTimeout);
|
|
175
|
+
resolve();
|
|
176
|
+
});
|
|
177
|
+
// Send shutdown message
|
|
178
|
+
this.worker.postMessage({ type: 'shutdown' });
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Terminate worker immediately
|
|
183
|
+
*/
|
|
184
|
+
terminate() {
|
|
185
|
+
this.status = 'idle';
|
|
186
|
+
return this.worker.terminate();
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Get worker health status
|
|
190
|
+
*/
|
|
191
|
+
getHealthStatus() {
|
|
192
|
+
return {
|
|
193
|
+
id: this.id,
|
|
194
|
+
pid: this.worker.threadId,
|
|
195
|
+
status: this.status,
|
|
196
|
+
eventsProcessed: this.eventsProcessed,
|
|
197
|
+
lastActivity: this.lastActivity,
|
|
198
|
+
memoryUsage: 0, // Will be updated by worker
|
|
199
|
+
cpuUsage: 0, // Will be updated by worker
|
|
200
|
+
errors: this.errors,
|
|
201
|
+
uptime: Date.now() - this.startTime
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
exports.ManagedWorker = ManagedWorker;
|
|
206
|
+
/**
|
|
207
|
+
* Worker pool manager for handling multiple worker threads
|
|
208
|
+
*/
|
|
209
|
+
class WorkerManager extends events_1.EventEmitter {
|
|
210
|
+
constructor(config, sharedBuffer, metricsCollector) {
|
|
211
|
+
super();
|
|
212
|
+
this.workers = new Map();
|
|
213
|
+
this.isShuttingDown = false;
|
|
214
|
+
this.config = config;
|
|
215
|
+
this.sharedBuffer = sharedBuffer;
|
|
216
|
+
this.metricsCollector = metricsCollector;
|
|
217
|
+
this.workerScript = path.join(__dirname, 'event-processor.worker.ts');
|
|
218
|
+
this.startHealthMonitoring();
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Initialize worker pool
|
|
222
|
+
*/
|
|
223
|
+
async initialize() {
|
|
224
|
+
console.log(`Initializing worker pool with ${this.config.workerCount} workers`);
|
|
225
|
+
const workerPromises = [];
|
|
226
|
+
for (let i = 0; i < this.config.workerCount; i++) {
|
|
227
|
+
const workerId = `worker_${i}`;
|
|
228
|
+
workerPromises.push(this.createWorker(workerId));
|
|
229
|
+
}
|
|
230
|
+
await Promise.all(workerPromises);
|
|
231
|
+
console.log(`Worker pool initialized with ${this.workers.size} workers`);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Create a new worker
|
|
235
|
+
*/
|
|
236
|
+
async createWorker(workerId) {
|
|
237
|
+
return new Promise((resolve, reject) => {
|
|
238
|
+
try {
|
|
239
|
+
const worker = new ManagedWorker(workerId, this.workerScript, this.config, this.sharedBuffer);
|
|
240
|
+
// Setup event handlers
|
|
241
|
+
worker.once('ready', () => {
|
|
242
|
+
console.log(`Worker ${workerId} is ready`);
|
|
243
|
+
resolve();
|
|
244
|
+
});
|
|
245
|
+
worker.on('error', (error) => {
|
|
246
|
+
console.error(`Worker ${workerId} error:`, error);
|
|
247
|
+
this.handleWorkerError(workerId, error);
|
|
248
|
+
});
|
|
249
|
+
worker.on('exit', (code) => {
|
|
250
|
+
console.log(`Worker ${workerId} exited with code ${code}`);
|
|
251
|
+
this.handleWorkerExit(workerId, code);
|
|
252
|
+
});
|
|
253
|
+
worker.on('event_processed', (data) => {
|
|
254
|
+
this.metricsCollector.recordEventProcessed(data.processingTime, 0 // queue latency - would need to be calculated
|
|
255
|
+
);
|
|
256
|
+
});
|
|
257
|
+
worker.on('worker_error', (error, eventType) => {
|
|
258
|
+
this.metricsCollector.recordEventDropped();
|
|
259
|
+
});
|
|
260
|
+
worker.on('health_status', (status) => {
|
|
261
|
+
this.metricsCollector.updateWorkerStatus(status.id, status);
|
|
262
|
+
});
|
|
263
|
+
this.workers.set(workerId, worker);
|
|
264
|
+
// Set timeout for worker initialization
|
|
265
|
+
setTimeout(() => {
|
|
266
|
+
if (worker.status !== 'running') {
|
|
267
|
+
reject(new Error(`Worker ${workerId} failed to initialize within timeout`));
|
|
268
|
+
}
|
|
269
|
+
}, 10000); // 10 second timeout
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
reject(error);
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Register event handler across all workers
|
|
278
|
+
*/
|
|
279
|
+
registerHandler(eventType, handler) {
|
|
280
|
+
console.log(`Registering handler for event type: ${eventType}`);
|
|
281
|
+
for (const worker of this.workers.values()) {
|
|
282
|
+
if (worker.status === 'running') {
|
|
283
|
+
worker.registerHandler(eventType, handler);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Handle worker error
|
|
289
|
+
*/
|
|
290
|
+
async handleWorkerError(workerId, error) {
|
|
291
|
+
console.error(`Handling error for worker ${workerId}:`, error);
|
|
292
|
+
const worker = this.workers.get(workerId);
|
|
293
|
+
if (!worker)
|
|
294
|
+
return;
|
|
295
|
+
// If worker has too many errors, restart it
|
|
296
|
+
if (worker.errors > this.config.reliabilityLimits.maxRetryAttempts) {
|
|
297
|
+
console.log(`Worker ${workerId} has too many errors, restarting`);
|
|
298
|
+
await this.restartWorker(workerId);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Handle worker exit
|
|
303
|
+
*/
|
|
304
|
+
async handleWorkerExit(workerId, code) {
|
|
305
|
+
console.log(`Worker ${workerId} exited with code ${code}`);
|
|
306
|
+
if (!this.isShuttingDown && code !== 0) {
|
|
307
|
+
console.log(`Restarting worker ${workerId} due to unexpected exit`);
|
|
308
|
+
await this.restartWorker(workerId);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Restart a worker
|
|
313
|
+
*/
|
|
314
|
+
async restartWorker(workerId) {
|
|
315
|
+
const oldWorker = this.workers.get(workerId);
|
|
316
|
+
if (oldWorker) {
|
|
317
|
+
try {
|
|
318
|
+
await oldWorker.shutdown(3000);
|
|
319
|
+
}
|
|
320
|
+
catch (error) {
|
|
321
|
+
console.warn(`Failed to shutdown worker ${workerId} gracefully:`, error);
|
|
322
|
+
await oldWorker.terminate();
|
|
323
|
+
}
|
|
324
|
+
this.workers.delete(workerId);
|
|
325
|
+
}
|
|
326
|
+
// Create new worker
|
|
327
|
+
try {
|
|
328
|
+
await this.createWorker(workerId);
|
|
329
|
+
console.log(`Worker ${workerId} restarted successfully`);
|
|
330
|
+
}
|
|
331
|
+
catch (error) {
|
|
332
|
+
console.error(`Failed to restart worker ${workerId}:`, error);
|
|
333
|
+
this.emit('worker_restart_failed', workerId, error);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Start health monitoring
|
|
338
|
+
*/
|
|
339
|
+
startHealthMonitoring() {
|
|
340
|
+
this.healthCheckInterval = setInterval(() => {
|
|
341
|
+
this.performHealthChecks();
|
|
342
|
+
}, this.config.monitoring.healthCheckInterval);
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Perform health checks on all workers
|
|
346
|
+
*/
|
|
347
|
+
performHealthChecks() {
|
|
348
|
+
for (const worker of this.workers.values()) {
|
|
349
|
+
if (worker.status === 'running') {
|
|
350
|
+
worker.requestHealthCheck();
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Get all worker statuses
|
|
356
|
+
*/
|
|
357
|
+
getWorkerStatuses() {
|
|
358
|
+
return Array.from(this.workers.values()).map(worker => worker.getHealthStatus());
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Get healthy worker count
|
|
362
|
+
*/
|
|
363
|
+
getHealthyWorkerCount() {
|
|
364
|
+
return Array.from(this.workers.values())
|
|
365
|
+
.filter(worker => worker.status === 'running').length;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Scale worker pool
|
|
369
|
+
*/
|
|
370
|
+
async scaleWorkers(targetCount) {
|
|
371
|
+
const currentCount = this.workers.size;
|
|
372
|
+
if (targetCount > currentCount) {
|
|
373
|
+
// Scale up
|
|
374
|
+
const workersToAdd = targetCount - currentCount;
|
|
375
|
+
const promises = [];
|
|
376
|
+
for (let i = 0; i < workersToAdd; i++) {
|
|
377
|
+
const workerId = `worker_${currentCount + i}`;
|
|
378
|
+
promises.push(this.createWorker(workerId));
|
|
379
|
+
}
|
|
380
|
+
await Promise.all(promises);
|
|
381
|
+
console.log(`Scaled up to ${this.workers.size} workers`);
|
|
382
|
+
}
|
|
383
|
+
else if (targetCount < currentCount) {
|
|
384
|
+
// Scale down
|
|
385
|
+
const workersToRemove = currentCount - targetCount;
|
|
386
|
+
const workerIds = Array.from(this.workers.keys()).slice(-workersToRemove);
|
|
387
|
+
const promises = workerIds.map(async (workerId) => {
|
|
388
|
+
const worker = this.workers.get(workerId);
|
|
389
|
+
if (worker) {
|
|
390
|
+
await worker.shutdown();
|
|
391
|
+
this.workers.delete(workerId);
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
await Promise.all(promises);
|
|
395
|
+
console.log(`Scaled down to ${this.workers.size} workers`);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Shutdown all workers
|
|
400
|
+
*/
|
|
401
|
+
async shutdown() {
|
|
402
|
+
console.log('Shutting down worker manager');
|
|
403
|
+
this.isShuttingDown = true;
|
|
404
|
+
// Clear health monitoring
|
|
405
|
+
if (this.healthCheckInterval) {
|
|
406
|
+
clearInterval(this.healthCheckInterval);
|
|
407
|
+
}
|
|
408
|
+
// Shutdown all workers
|
|
409
|
+
const shutdownPromises = Array.from(this.workers.values()).map(async (worker) => {
|
|
410
|
+
try {
|
|
411
|
+
await worker.shutdown(this.config.reliabilityLimits.gracefulShutdownTimeout);
|
|
412
|
+
}
|
|
413
|
+
catch (error) {
|
|
414
|
+
console.warn(`Failed to shutdown worker ${worker.id} gracefully:`, error);
|
|
415
|
+
await worker.terminate();
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
await Promise.all(shutdownPromises);
|
|
419
|
+
this.workers.clear();
|
|
420
|
+
console.log('Worker manager shutdown complete');
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Get worker manager statistics
|
|
424
|
+
*/
|
|
425
|
+
getStatistics() {
|
|
426
|
+
const workers = Array.from(this.workers.values());
|
|
427
|
+
return {
|
|
428
|
+
totalWorkers: workers.length,
|
|
429
|
+
healthyWorkers: workers.filter(w => w.status === 'running').length,
|
|
430
|
+
totalEventsProcessed: workers.reduce((sum, w) => sum + w.eventsProcessed, 0),
|
|
431
|
+
totalErrors: workers.reduce((sum, w) => sum + w.errors, 0)
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
exports.WorkerManager = WorkerManager;
|
|
436
|
+
//# sourceMappingURL=worker-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-manager.js","sourceRoot":"","sources":["../../../src/events/worker/worker-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,27 +1 @@
|
|
|
1
|
-
import { FastifyRequest, FastifyReply } from 'fastify';
|
|
2
|
-
import { AuthManager } from '../../auth/AuthManager';
|
|
3
|
-
declare const authManager: AuthManager;
|
|
4
|
-
/**
|
|
5
|
-
* Global JWT Authentication Middleware
|
|
6
|
-
* Validates JWT tokens from Authorization header
|
|
7
|
-
* Adds user information to request context
|
|
8
|
-
*/
|
|
9
|
-
export declare const jwtAuthMiddleware: (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
|
|
10
|
-
/**
|
|
11
|
-
* Optional Authentication Middleware
|
|
12
|
-
* Similar to jwtAuthMiddleware but doesn't reject requests without tokens
|
|
13
|
-
* Useful for endpoints that work with or without authentication
|
|
14
|
-
*/
|
|
15
|
-
export declare const optionalJwtAuthMiddleware: (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
|
|
16
|
-
/**
|
|
17
|
-
* Role-based Authorization Middleware Factory
|
|
18
|
-
* Creates middleware that checks if authenticated user has required roles
|
|
19
|
-
*/
|
|
20
|
-
export declare const requireRoles: (requiredRoles: string[]) => (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
|
|
21
|
-
/**
|
|
22
|
-
* Permission-based Authorization Middleware Factory
|
|
23
|
-
* Creates middleware that checks if authenticated user has required permissions
|
|
24
|
-
*/
|
|
25
|
-
export declare const requirePermissions: (requiredPermissions: string[]) => (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
|
|
26
|
-
export { authManager };
|
|
27
1
|
//# sourceMappingURL=auth.middleware.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.middleware.d.ts","sourceRoot":"","sources":["../../../src/examples/auth/auth.middleware.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.middleware.d.ts","sourceRoot":"","sources":["../../../src/examples/auth/auth.middleware.ts"],"names":[],"mappings":""}
|
|
@@ -1,187 +1,2 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.authManager = exports.requirePermissions = exports.requireRoles = exports.optionalJwtAuthMiddleware = exports.jwtAuthMiddleware = void 0;
|
|
4
|
-
const AuthManager_1 = require("../../auth/AuthManager");
|
|
5
|
-
const JwtStrategy_1 = require("../../auth/strategies/JwtStrategy");
|
|
6
|
-
const RedisTokenStorage_1 = require("../../auth/storage/RedisTokenStorage");
|
|
7
|
-
// Mock Redis client for demo
|
|
8
|
-
const mockRedisClient = {
|
|
9
|
-
set: async (key, value, options) => 'OK',
|
|
10
|
-
get: async (key) => null,
|
|
11
|
-
del: async (key) => 1,
|
|
12
|
-
exists: async (key) => 0
|
|
13
|
-
};
|
|
14
|
-
// Initialize auth system
|
|
15
|
-
const tokenStorage = new RedisTokenStorage_1.RedisTokenStorage(mockRedisClient);
|
|
16
|
-
const jwtStrategy = new JwtStrategy_1.JwtStrategy();
|
|
17
|
-
const authManager = new AuthManager_1.AuthManager({
|
|
18
|
-
defaultStrategy: 'jwt',
|
|
19
|
-
tokenStorage
|
|
20
|
-
});
|
|
21
|
-
exports.authManager = authManager;
|
|
22
|
-
// Initialize auth system
|
|
23
|
-
let authInitialized = false;
|
|
24
|
-
async function initializeAuth() {
|
|
25
|
-
if (!authInitialized) {
|
|
26
|
-
await authManager.registerStrategy(jwtStrategy, {
|
|
27
|
-
strategy: 'jwt',
|
|
28
|
-
options: {
|
|
29
|
-
secret: process.env.JWT_SECRET || 'your-secret-key',
|
|
30
|
-
accessTokenExpiry: '15m',
|
|
31
|
-
refreshTokenExpiry: '7d',
|
|
32
|
-
issuer: 'bootifyjs-auth',
|
|
33
|
-
audience: 'bootifyjs-app',
|
|
34
|
-
isDefault: true
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
authInitialized = true;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Global JWT Authentication Middleware
|
|
42
|
-
* Validates JWT tokens from Authorization header
|
|
43
|
-
* Adds user information to request context
|
|
44
|
-
*/
|
|
45
|
-
const jwtAuthMiddleware = async (request, reply) => {
|
|
46
|
-
await initializeAuth();
|
|
47
|
-
// Extract token from Authorization header
|
|
48
|
-
const authHeader = request.headers.authorization;
|
|
49
|
-
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|
50
|
-
reply.code(401).send({
|
|
51
|
-
error: 'UNAUTHORIZED',
|
|
52
|
-
message: 'Missing or invalid Authorization header. Expected format: Bearer <token>'
|
|
53
|
-
});
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
const token = authHeader.substring(7); // Remove 'Bearer ' prefix
|
|
57
|
-
try {
|
|
58
|
-
// Create auth context
|
|
59
|
-
const context = {
|
|
60
|
-
type: 'validate',
|
|
61
|
-
strategy: 'jwt',
|
|
62
|
-
request,
|
|
63
|
-
headers: request.headers,
|
|
64
|
-
body: request.body,
|
|
65
|
-
query: request.query
|
|
66
|
-
};
|
|
67
|
-
// Validate token using auth manager
|
|
68
|
-
const validationResult = await authManager.validate(token, context, 'jwt');
|
|
69
|
-
if (!validationResult.success || !validationResult.user) {
|
|
70
|
-
reply.code(401).send({
|
|
71
|
-
error: 'INVALID_TOKEN',
|
|
72
|
-
message: validationResult.error || 'Token validation failed'
|
|
73
|
-
});
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
// Add user information to request
|
|
77
|
-
request.user = validationResult.user;
|
|
78
|
-
request.authStrategy = 'jwt';
|
|
79
|
-
request.isAuthenticated = true;
|
|
80
|
-
}
|
|
81
|
-
catch (error) {
|
|
82
|
-
const errorMessage = error instanceof Error ? error.message : 'Authentication failed';
|
|
83
|
-
reply.code(401).send({
|
|
84
|
-
error: 'AUTH_ERROR',
|
|
85
|
-
message: errorMessage
|
|
86
|
-
});
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
exports.jwtAuthMiddleware = jwtAuthMiddleware;
|
|
91
|
-
/**
|
|
92
|
-
* Optional Authentication Middleware
|
|
93
|
-
* Similar to jwtAuthMiddleware but doesn't reject requests without tokens
|
|
94
|
-
* Useful for endpoints that work with or without authentication
|
|
95
|
-
*/
|
|
96
|
-
const optionalJwtAuthMiddleware = async (request, reply) => {
|
|
97
|
-
await initializeAuth();
|
|
98
|
-
// Extract token from Authorization header
|
|
99
|
-
const authHeader = request.headers.authorization;
|
|
100
|
-
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|
101
|
-
// No token provided, continue without authentication
|
|
102
|
-
request.isAuthenticated = false;
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
const token = authHeader.substring(7); // Remove 'Bearer ' prefix
|
|
106
|
-
try {
|
|
107
|
-
// Create auth context
|
|
108
|
-
const context = {
|
|
109
|
-
type: 'validate',
|
|
110
|
-
strategy: 'jwt',
|
|
111
|
-
request,
|
|
112
|
-
headers: request.headers,
|
|
113
|
-
body: request.body,
|
|
114
|
-
query: request.query
|
|
115
|
-
};
|
|
116
|
-
// Validate token using auth manager
|
|
117
|
-
const validationResult = await authManager.validate(token, context, 'jwt');
|
|
118
|
-
if (validationResult.success && validationResult.user) {
|
|
119
|
-
// Add user information to request
|
|
120
|
-
request.user = validationResult.user;
|
|
121
|
-
request.authStrategy = 'jwt';
|
|
122
|
-
request.isAuthenticated = true;
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
// Invalid token, but continue without authentication
|
|
126
|
-
request.isAuthenticated = false;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
catch (error) {
|
|
130
|
-
// Error occurred, but continue without authentication
|
|
131
|
-
request.isAuthenticated = false;
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
exports.optionalJwtAuthMiddleware = optionalJwtAuthMiddleware;
|
|
135
|
-
/**
|
|
136
|
-
* Role-based Authorization Middleware Factory
|
|
137
|
-
* Creates middleware that checks if authenticated user has required roles
|
|
138
|
-
*/
|
|
139
|
-
const requireRoles = (requiredRoles) => {
|
|
140
|
-
return async (request, reply) => {
|
|
141
|
-
const user = request.user;
|
|
142
|
-
const isAuthenticated = request.isAuthenticated;
|
|
143
|
-
if (!isAuthenticated || !user) {
|
|
144
|
-
reply.code(401).send({
|
|
145
|
-
error: 'UNAUTHORIZED',
|
|
146
|
-
message: 'Authentication required'
|
|
147
|
-
});
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
const hasRequiredRole = requiredRoles.some(role => user.roles.includes(role));
|
|
151
|
-
if (!hasRequiredRole) {
|
|
152
|
-
reply.code(403).send({
|
|
153
|
-
error: 'FORBIDDEN',
|
|
154
|
-
message: `Access denied. Required roles: ${requiredRoles.join(', ')}`
|
|
155
|
-
});
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
|
-
};
|
|
160
|
-
exports.requireRoles = requireRoles;
|
|
161
|
-
/**
|
|
162
|
-
* Permission-based Authorization Middleware Factory
|
|
163
|
-
* Creates middleware that checks if authenticated user has required permissions
|
|
164
|
-
*/
|
|
165
|
-
const requirePermissions = (requiredPermissions) => {
|
|
166
|
-
return async (request, reply) => {
|
|
167
|
-
const user = request.user;
|
|
168
|
-
const isAuthenticated = request.isAuthenticated;
|
|
169
|
-
if (!isAuthenticated || !user) {
|
|
170
|
-
reply.code(401).send({
|
|
171
|
-
error: 'UNAUTHORIZED',
|
|
172
|
-
message: 'Authentication required'
|
|
173
|
-
});
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
const hasRequiredPermission = requiredPermissions.some(permission => user.permissions.includes(permission));
|
|
177
|
-
if (!hasRequiredPermission) {
|
|
178
|
-
reply.code(403).send({
|
|
179
|
-
error: 'FORBIDDEN',
|
|
180
|
-
message: `Access denied. Required permissions: ${requiredPermissions.join(', ')}`
|
|
181
|
-
});
|
|
182
|
-
return;
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
};
|
|
186
|
-
exports.requirePermissions = requirePermissions;
|
|
187
2
|
//# sourceMappingURL=auth.middleware.js.map
|