@morojs/moro 1.6.5 → 1.6.8

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 (200) hide show
  1. package/README.md +20 -4
  2. package/dist/core/auth/morojs-adapter.js +17 -14
  3. package/dist/core/auth/morojs-adapter.js.map +1 -1
  4. package/dist/core/config/config-sources.js +44 -0
  5. package/dist/core/config/config-sources.js.map +1 -1
  6. package/dist/core/database/adapters/drizzle.js +5 -5
  7. package/dist/core/database/adapters/drizzle.js.map +1 -1
  8. package/dist/core/database/adapters/mongodb.js +5 -1
  9. package/dist/core/database/adapters/mongodb.js.map +1 -1
  10. package/dist/core/database/adapters/mysql.js +5 -1
  11. package/dist/core/database/adapters/mysql.js.map +1 -1
  12. package/dist/core/database/adapters/postgresql.js +1 -1
  13. package/dist/core/database/adapters/postgresql.js.map +1 -1
  14. package/dist/core/database/adapters/redis.js +2 -2
  15. package/dist/core/database/adapters/redis.js.map +1 -1
  16. package/dist/core/database/adapters/sqlite.js +5 -1
  17. package/dist/core/database/adapters/sqlite.js.map +1 -1
  18. package/dist/core/docs/index.js.map +1 -1
  19. package/dist/core/docs/simple-docs.js +2 -1
  20. package/dist/core/docs/simple-docs.js.map +1 -1
  21. package/dist/core/docs/swagger-ui.js +1 -0
  22. package/dist/core/docs/swagger-ui.js.map +1 -1
  23. package/dist/core/docs/zod-to-openapi.js +4 -0
  24. package/dist/core/docs/zod-to-openapi.js.map +1 -1
  25. package/dist/core/events/event-bus.d.ts +1 -1
  26. package/dist/core/events/event-bus.js +8 -4
  27. package/dist/core/events/event-bus.js.map +1 -1
  28. package/dist/core/framework.d.ts +1 -1
  29. package/dist/core/framework.js +3 -1
  30. package/dist/core/framework.js.map +1 -1
  31. package/dist/core/graphql/adapter.d.ts +73 -0
  32. package/dist/core/graphql/adapter.js +2 -0
  33. package/dist/core/graphql/adapter.js.map +1 -0
  34. package/dist/core/graphql/adapters/graphql-js-adapter.d.ts +26 -0
  35. package/dist/core/graphql/adapters/graphql-js-adapter.js +229 -0
  36. package/dist/core/graphql/adapters/graphql-js-adapter.js.map +1 -0
  37. package/dist/core/graphql/core.d.ts +60 -0
  38. package/dist/core/graphql/core.js +165 -0
  39. package/dist/core/graphql/core.js.map +1 -0
  40. package/dist/core/graphql/index.d.ts +4 -0
  41. package/dist/core/graphql/index.js +4 -0
  42. package/dist/core/graphql/index.js.map +1 -0
  43. package/dist/core/graphql/loader.d.ts +9 -0
  44. package/dist/core/graphql/loader.js +32 -0
  45. package/dist/core/graphql/loader.js.map +1 -0
  46. package/dist/core/graphql/types.d.ts +211 -0
  47. package/dist/core/graphql/types.js +2 -0
  48. package/dist/core/graphql/types.js.map +1 -0
  49. package/dist/core/http/http-server.d.ts +7 -0
  50. package/dist/core/http/http-server.js +267 -123
  51. package/dist/core/http/http-server.js.map +1 -1
  52. package/dist/core/http/utils/uws-worker-clustering.d.ts +28 -0
  53. package/dist/core/http/utils/uws-worker-clustering.js +313 -0
  54. package/dist/core/http/utils/uws-worker-clustering.js.map +1 -0
  55. package/dist/core/http/uws-http-server.d.ts +7 -1
  56. package/dist/core/http/uws-http-server.js +272 -189
  57. package/dist/core/http/uws-http-server.js.map +1 -1
  58. package/dist/core/jobs/cron-parser.d.ts +62 -0
  59. package/dist/core/jobs/cron-parser.js +239 -0
  60. package/dist/core/jobs/cron-parser.js.map +1 -0
  61. package/dist/core/jobs/index.d.ts +12 -0
  62. package/dist/core/jobs/index.js +9 -0
  63. package/dist/core/jobs/index.js.map +1 -0
  64. package/dist/core/jobs/job-executor.d.ts +134 -0
  65. package/dist/core/jobs/job-executor.js +413 -0
  66. package/dist/core/jobs/job-executor.js.map +1 -0
  67. package/dist/core/jobs/job-scheduler.d.ts +214 -0
  68. package/dist/core/jobs/job-scheduler.js +551 -0
  69. package/dist/core/jobs/job-scheduler.js.map +1 -0
  70. package/dist/core/jobs/job-state-manager.d.ts +158 -0
  71. package/dist/core/jobs/job-state-manager.js +444 -0
  72. package/dist/core/jobs/job-state-manager.js.map +1 -0
  73. package/dist/core/jobs/leader-election.d.ts +124 -0
  74. package/dist/core/jobs/leader-election.js +481 -0
  75. package/dist/core/jobs/leader-election.js.map +1 -0
  76. package/dist/core/jobs/types.d.ts +151 -0
  77. package/dist/core/jobs/types.js +4 -0
  78. package/dist/core/jobs/types.js.map +1 -0
  79. package/dist/core/jobs/utils.d.ts +95 -0
  80. package/dist/core/jobs/utils.js +258 -0
  81. package/dist/core/jobs/utils.js.map +1 -0
  82. package/dist/core/logger/filters.js +2 -0
  83. package/dist/core/logger/filters.js.map +1 -1
  84. package/dist/core/logger/logger.d.ts +7 -5
  85. package/dist/core/logger/logger.js +68 -27
  86. package/dist/core/logger/logger.js.map +1 -1
  87. package/dist/core/logger/outputs.js +2 -0
  88. package/dist/core/logger/outputs.js.map +1 -1
  89. package/dist/core/middleware/built-in/auth/helpers.js +1 -1
  90. package/dist/core/middleware/built-in/auth/helpers.js.map +1 -1
  91. package/dist/core/middleware/built-in/auth/jwt-helpers.js +1 -1
  92. package/dist/core/middleware/built-in/auth/jwt-helpers.js.map +1 -1
  93. package/dist/core/middleware/built-in/auth/providers.js +1 -1
  94. package/dist/core/middleware/built-in/auth/providers.js.map +1 -1
  95. package/dist/core/middleware/built-in/cache/adapters/cache/file.js +3 -3
  96. package/dist/core/middleware/built-in/cache/adapters/cache/file.js.map +1 -1
  97. package/dist/core/middleware/built-in/cache/adapters/cache/memory.js +1 -0
  98. package/dist/core/middleware/built-in/cache/adapters/cache/memory.js.map +1 -1
  99. package/dist/core/middleware/built-in/cache/adapters/cache/redis.js +1 -1
  100. package/dist/core/middleware/built-in/cache/adapters/cache/redis.js.map +1 -1
  101. package/dist/core/middleware/built-in/cdn/adapters/cdn/azure.d.ts +8 -0
  102. package/dist/core/middleware/built-in/cdn/adapters/cdn/azure.js +100 -7
  103. package/dist/core/middleware/built-in/cdn/adapters/cdn/azure.js.map +1 -1
  104. package/dist/core/middleware/built-in/cdn/adapters/cdn/cloudflare.d.ts +6 -0
  105. package/dist/core/middleware/built-in/cdn/adapters/cdn/cloudflare.js +97 -13
  106. package/dist/core/middleware/built-in/cdn/adapters/cdn/cloudflare.js.map +1 -1
  107. package/dist/core/middleware/built-in/cdn/adapters/cdn/cloudfront.js +1 -1
  108. package/dist/core/middleware/built-in/cdn/adapters/cdn/cloudfront.js.map +1 -1
  109. package/dist/core/middleware/built-in/cookie/hook.d.ts +1 -1
  110. package/dist/core/middleware/built-in/cookie/hook.js +2 -2
  111. package/dist/core/middleware/built-in/cookie/hook.js.map +1 -1
  112. package/dist/core/middleware/built-in/csrf/core.js +1 -0
  113. package/dist/core/middleware/built-in/csrf/core.js.map +1 -1
  114. package/dist/core/middleware/built-in/graphql/core.d.ts +11 -0
  115. package/dist/core/middleware/built-in/graphql/core.js +24 -0
  116. package/dist/core/middleware/built-in/graphql/core.js.map +1 -0
  117. package/dist/core/middleware/built-in/graphql/helpers.d.ts +69 -0
  118. package/dist/core/middleware/built-in/graphql/helpers.js +187 -0
  119. package/dist/core/middleware/built-in/graphql/helpers.js.map +1 -0
  120. package/dist/core/middleware/built-in/graphql/hook.d.ts +7 -0
  121. package/dist/core/middleware/built-in/graphql/hook.js +78 -0
  122. package/dist/core/middleware/built-in/graphql/hook.js.map +1 -0
  123. package/dist/core/middleware/built-in/graphql/index.d.ts +5 -0
  124. package/dist/core/middleware/built-in/graphql/index.js +5 -0
  125. package/dist/core/middleware/built-in/graphql/index.js.map +1 -0
  126. package/dist/core/middleware/built-in/graphql/middleware.d.ts +7 -0
  127. package/dist/core/middleware/built-in/graphql/middleware.js +54 -0
  128. package/dist/core/middleware/built-in/graphql/middleware.js.map +1 -0
  129. package/dist/core/middleware/built-in/graphql/subscriptions.d.ts +20 -0
  130. package/dist/core/middleware/built-in/graphql/subscriptions.js +37 -0
  131. package/dist/core/middleware/built-in/graphql/subscriptions.js.map +1 -0
  132. package/dist/core/middleware/built-in/index.d.ts +2 -1
  133. package/dist/core/middleware/built-in/index.js +3 -0
  134. package/dist/core/middleware/built-in/index.js.map +1 -1
  135. package/dist/core/middleware/built-in/rate-limit/core.d.ts +5 -0
  136. package/dist/core/middleware/built-in/rate-limit/core.js +16 -8
  137. package/dist/core/middleware/built-in/rate-limit/core.js.map +1 -1
  138. package/dist/core/middleware/built-in/validation/core.js +42 -19
  139. package/dist/core/middleware/built-in/validation/core.js.map +1 -1
  140. package/dist/core/middleware/index.js +1 -0
  141. package/dist/core/middleware/index.js.map +1 -1
  142. package/dist/core/modules/auto-discovery.js +5 -4
  143. package/dist/core/modules/auto-discovery.js.map +1 -1
  144. package/dist/core/modules/modules.js.map +1 -1
  145. package/dist/core/networking/adapters/socketio-adapter.js +1 -1
  146. package/dist/core/networking/adapters/socketio-adapter.js.map +1 -1
  147. package/dist/core/networking/adapters/uws-adapter.js +7 -2
  148. package/dist/core/networking/adapters/uws-adapter.js.map +1 -1
  149. package/dist/core/networking/adapters/ws-adapter.js +5 -2
  150. package/dist/core/networking/adapters/ws-adapter.js.map +1 -1
  151. package/dist/core/networking/websocket-manager.js +2 -0
  152. package/dist/core/networking/websocket-manager.js.map +1 -1
  153. package/dist/core/pooling/object-pool-manager.d.ts +8 -2
  154. package/dist/core/pooling/object-pool-manager.js +38 -18
  155. package/dist/core/pooling/object-pool-manager.js.map +1 -1
  156. package/dist/core/routing/app-integration.d.ts +3 -3
  157. package/dist/core/routing/app-integration.js +1 -1
  158. package/dist/core/routing/app-integration.js.map +1 -1
  159. package/dist/core/routing/index.d.ts +1 -1
  160. package/dist/core/routing/index.js +1 -1
  161. package/dist/core/routing/index.js.map +1 -1
  162. package/dist/core/routing/path-matcher.d.ts +6 -0
  163. package/dist/core/routing/path-matcher.js +46 -7
  164. package/dist/core/routing/path-matcher.js.map +1 -1
  165. package/dist/core/routing/unified-router.d.ts +4 -0
  166. package/dist/core/routing/unified-router.js +104 -43
  167. package/dist/core/routing/unified-router.js.map +1 -1
  168. package/dist/core/runtime/base-adapter.js +3 -3
  169. package/dist/core/runtime/base-adapter.js.map +1 -1
  170. package/dist/core/runtime/cloudflare-workers-adapter.js +1 -1
  171. package/dist/core/runtime/cloudflare-workers-adapter.js.map +1 -1
  172. package/dist/core/runtime/node-adapter.d.ts +1 -1
  173. package/dist/core/runtime/node-adapter.js +7 -4
  174. package/dist/core/runtime/node-adapter.js.map +1 -1
  175. package/dist/core/runtime/vercel-edge-adapter.js +1 -0
  176. package/dist/core/runtime/vercel-edge-adapter.js.map +1 -1
  177. package/dist/core/utilities/circuit-breaker.d.ts +9 -2
  178. package/dist/core/utilities/circuit-breaker.js +32 -3
  179. package/dist/core/utilities/circuit-breaker.js.map +1 -1
  180. package/dist/core/utilities/container.js +6 -0
  181. package/dist/core/utilities/container.js.map +1 -1
  182. package/dist/core/utilities/hooks.d.ts +4 -0
  183. package/dist/core/utilities/hooks.js +134 -22
  184. package/dist/core/utilities/hooks.js.map +1 -1
  185. package/dist/core/validation/index.js +6 -1
  186. package/dist/core/validation/index.js.map +1 -1
  187. package/dist/index.d.ts +6 -0
  188. package/dist/index.js +5 -0
  189. package/dist/index.js.map +1 -1
  190. package/dist/moro.d.ts +154 -1
  191. package/dist/moro.js +592 -16
  192. package/dist/moro.js.map +1 -1
  193. package/dist/types/config.d.ts +28 -0
  194. package/dist/types/core.d.ts +1 -0
  195. package/dist/types/events.d.ts +1 -1
  196. package/dist/types/events.js +1 -0
  197. package/dist/types/events.js.map +1 -1
  198. package/dist/types/logger.d.ts +1 -0
  199. package/dist/types/module.d.ts +2 -2
  200. package/package.json +21 -1
@@ -0,0 +1,413 @@
1
+ // Production-grade Job Executor
2
+ // Handles job execution with retry logic, timeout, circuit breaker, and memory monitoring
3
+ import { EventEmitter } from 'events';
4
+ import { CircuitBreaker } from '../utilities/circuit-breaker.js';
5
+ // Reference to global AbortController
6
+ const AbortControllerClass = globalThis.AbortController;
7
+ /**
8
+ * JobExecutor - Executes jobs with production-grade resilience
9
+ * Features:
10
+ * - Configurable retry with exponential backoff + jitter
11
+ * - Timeout enforcement
12
+ * - Circuit breaker integration
13
+ * - Memory leak detection
14
+ * - Graceful cancellation
15
+ */
16
+ export class JobExecutor extends EventEmitter {
17
+ options;
18
+ logger;
19
+ circuitBreakers = new Map();
20
+ activeExecutions = new Map();
21
+ isShuttingDown = false;
22
+ constructor(logger, options = {}) {
23
+ super();
24
+ this.logger = logger;
25
+ // Set defaults
26
+ this.options = {
27
+ maxRetries: options.maxRetries ?? 3,
28
+ retryDelay: options.retryDelay ?? 1000,
29
+ retryBackoff: options.retryBackoff ?? 'exponential',
30
+ retryBackoffMultiplier: options.retryBackoffMultiplier ?? 2,
31
+ maxRetryDelay: options.maxRetryDelay ?? 60000,
32
+ timeout: options.timeout ?? 300000, // 5 minutes default
33
+ enableCircuitBreaker: options.enableCircuitBreaker ?? true,
34
+ circuitBreakerThreshold: options.circuitBreakerThreshold ?? 5,
35
+ circuitBreakerResetTimeout: options.circuitBreakerResetTimeout ?? 60000,
36
+ enableMemoryMonitoring: options.enableMemoryMonitoring ?? true,
37
+ memoryThreshold: options.memoryThreshold ?? 512, // 512MB default
38
+ };
39
+ this.logger.debug('JobExecutor initialized', 'JobExecutor', { options: this.options });
40
+ }
41
+ /**
42
+ * Execute a job with full resilience features
43
+ */
44
+ async execute(jobId, executionId, jobFn, context) {
45
+ if (this.isShuttingDown) {
46
+ throw new Error('JobExecutor is shutting down');
47
+ }
48
+ const ctx = context || {
49
+ jobId,
50
+ executionId,
51
+ attempt: 1,
52
+ startTime: new Date(),
53
+ };
54
+ const startTime = Date.now();
55
+ const abortController = new AbortControllerClass();
56
+ this.activeExecutions.set(executionId, abortController);
57
+ let lastError;
58
+ let attempts = 0;
59
+ let circuitBreakerTripped = false;
60
+ let timedOut = false;
61
+ try {
62
+ // Check memory before execution
63
+ if (this.options.enableMemoryMonitoring) {
64
+ await this.checkMemoryUsage(jobId);
65
+ }
66
+ // Execute with retries
67
+ while (attempts <= this.options.maxRetries) {
68
+ attempts++;
69
+ ctx.attempt = attempts;
70
+ try {
71
+ // Check circuit breaker
72
+ if (this.options.enableCircuitBreaker) {
73
+ const breaker = this.getCircuitBreaker(jobId);
74
+ if (breaker.isOpen()) {
75
+ circuitBreakerTripped = true;
76
+ throw new Error(`Circuit breaker open for job ${jobId}`);
77
+ }
78
+ }
79
+ // Execute with timeout
80
+ const result = await this.executeWithTimeout(jobFn, ctx, abortController.signal);
81
+ // Success - record in circuit breaker
82
+ if (this.options.enableCircuitBreaker) {
83
+ const breaker = this.getCircuitBreaker(jobId);
84
+ breaker.recordSuccess();
85
+ }
86
+ const duration = Date.now() - startTime;
87
+ const memoryUsed = this.getMemoryUsage();
88
+ this.logger.debug(`Job executed successfully: ${jobId}`, 'JobExecutor', {
89
+ executionId,
90
+ attempts,
91
+ duration,
92
+ memoryUsed,
93
+ });
94
+ this.emit('execution:success', {
95
+ jobId,
96
+ executionId,
97
+ attempts,
98
+ duration,
99
+ memoryUsed,
100
+ });
101
+ return {
102
+ success: true,
103
+ value: result,
104
+ attempts,
105
+ duration,
106
+ memoryUsed,
107
+ circuitBreakerTripped: false,
108
+ timedOut: false,
109
+ };
110
+ }
111
+ catch (error) {
112
+ lastError = error instanceof Error ? error : new Error(String(error));
113
+ // Check if it's a timeout
114
+ if (lastError.name === 'TimeoutError' || lastError.message.includes('timeout')) {
115
+ timedOut = true;
116
+ }
117
+ // Record failure in circuit breaker
118
+ if (this.options.enableCircuitBreaker && !circuitBreakerTripped) {
119
+ const breaker = this.getCircuitBreaker(jobId);
120
+ breaker.recordFailure();
121
+ }
122
+ this.logger.warn(`Job execution failed: ${jobId} (attempt ${attempts}/${this.options.maxRetries + 1})`, 'JobExecutor', {
123
+ executionId,
124
+ error: lastError.message,
125
+ timedOut,
126
+ circuitBreakerTripped,
127
+ });
128
+ this.emit('execution:retry', {
129
+ jobId,
130
+ executionId,
131
+ attempt: attempts,
132
+ maxAttempts: this.options.maxRetries + 1,
133
+ error: lastError,
134
+ timedOut,
135
+ });
136
+ // Don't retry if circuit breaker tripped or shutting down
137
+ if (circuitBreakerTripped || this.isShuttingDown) {
138
+ break;
139
+ }
140
+ // Calculate retry delay with backoff and jitter
141
+ if (attempts <= this.options.maxRetries) {
142
+ const delay = this.calculateRetryDelay(attempts);
143
+ await this.sleep(delay);
144
+ }
145
+ }
146
+ }
147
+ // All retries exhausted
148
+ const duration = Date.now() - startTime;
149
+ this.logger.error(`Job execution failed after ${attempts} attempts: ${jobId}`, 'JobExecutor', {
150
+ executionId,
151
+ error: lastError?.message,
152
+ timedOut,
153
+ circuitBreakerTripped,
154
+ });
155
+ this.emit('execution:failed', {
156
+ jobId,
157
+ executionId,
158
+ attempts,
159
+ duration,
160
+ error: lastError,
161
+ timedOut,
162
+ circuitBreakerTripped,
163
+ });
164
+ return {
165
+ success: false,
166
+ error: lastError,
167
+ attempts,
168
+ duration,
169
+ circuitBreakerTripped,
170
+ timedOut,
171
+ };
172
+ }
173
+ finally {
174
+ this.activeExecutions.delete(executionId);
175
+ // Force GC if memory threshold exceeded
176
+ if (this.options.enableMemoryMonitoring) {
177
+ const memUsage = process.memoryUsage();
178
+ const heapUsedMB = memUsage.heapUsed / 1024 / 1024;
179
+ if (heapUsedMB > this.options.memoryThreshold * 0.9 && globalThis.gc) {
180
+ this.logger.warn('High memory usage detected, triggering GC', 'JobExecutor', {
181
+ heapUsedMB: Math.round(heapUsedMB),
182
+ threshold: this.options.memoryThreshold,
183
+ });
184
+ globalThis.gc();
185
+ }
186
+ }
187
+ }
188
+ }
189
+ /**
190
+ * Execute job function with timeout
191
+ */
192
+ async executeWithTimeout(jobFn, context, signal) {
193
+ return new Promise((resolve, reject) => {
194
+ // Setup timeout
195
+ const timeoutId = setTimeout(() => {
196
+ const error = new Error(`Job execution timeout after ${this.options.timeout}ms`);
197
+ error.name = 'TimeoutError';
198
+ reject(error);
199
+ }, this.options.timeout);
200
+ // Setup abort handler
201
+ const abortHandler = () => {
202
+ clearTimeout(timeoutId);
203
+ reject(new Error('Job execution cancelled'));
204
+ };
205
+ if (signal.aborted) {
206
+ clearTimeout(timeoutId);
207
+ reject(new Error('Job execution cancelled'));
208
+ return;
209
+ }
210
+ signal.addEventListener('abort', abortHandler, { once: true });
211
+ // Execute job
212
+ Promise.resolve()
213
+ .then(() => jobFn(context))
214
+ .then(result => {
215
+ clearTimeout(timeoutId);
216
+ signal.removeEventListener('abort', abortHandler);
217
+ resolve(result);
218
+ })
219
+ .catch(error => {
220
+ clearTimeout(timeoutId);
221
+ signal.removeEventListener('abort', abortHandler);
222
+ reject(error);
223
+ });
224
+ });
225
+ }
226
+ /**
227
+ * Calculate retry delay with backoff and jitter
228
+ */
229
+ calculateRetryDelay(attempt) {
230
+ let delay;
231
+ if (this.options.retryBackoff === 'exponential') {
232
+ delay = this.options.retryDelay * Math.pow(this.options.retryBackoffMultiplier, attempt - 1);
233
+ }
234
+ else {
235
+ delay = this.options.retryDelay * attempt;
236
+ }
237
+ // Cap at max delay
238
+ delay = Math.min(delay, this.options.maxRetryDelay);
239
+ // Add jitter (±20%)
240
+ const jitter = delay * 0.2 * (Math.random() * 2 - 1);
241
+ delay = Math.max(0, delay + jitter);
242
+ return Math.floor(delay);
243
+ }
244
+ /**
245
+ * Sleep helper
246
+ */
247
+ sleep(ms) {
248
+ return new Promise(resolve => setTimeout(resolve, ms));
249
+ }
250
+ /**
251
+ * Get or create circuit breaker for job
252
+ */
253
+ getCircuitBreaker(jobId) {
254
+ let breaker = this.circuitBreakers.get(jobId);
255
+ if (!breaker) {
256
+ breaker = new CircuitBreaker({
257
+ failureThreshold: this.options.circuitBreakerThreshold,
258
+ resetTimeout: this.options.circuitBreakerResetTimeout,
259
+ });
260
+ // Log circuit breaker state changes
261
+ breaker.on('open', () => {
262
+ this.logger.error(`Circuit breaker opened for job: ${jobId}`);
263
+ this.emit('circuit-breaker:open', { jobId });
264
+ });
265
+ breaker.on('halfOpen', () => {
266
+ this.logger.info(`Circuit breaker half-open for job: ${jobId}`);
267
+ this.emit('circuit-breaker:half-open', { jobId });
268
+ });
269
+ breaker.on('closed', () => {
270
+ this.logger.info(`Circuit breaker closed for job: ${jobId}`);
271
+ this.emit('circuit-breaker:closed', { jobId });
272
+ });
273
+ this.circuitBreakers.set(jobId, breaker);
274
+ }
275
+ return breaker;
276
+ }
277
+ /**
278
+ * Check memory usage before execution
279
+ */
280
+ async checkMemoryUsage(jobId) {
281
+ const memUsage = process.memoryUsage();
282
+ const heapUsedMB = memUsage.heapUsed / 1024 / 1024;
283
+ if (heapUsedMB > this.options.memoryThreshold) {
284
+ const error = `Memory threshold exceeded: ${Math.round(heapUsedMB)}MB / ${this.options.memoryThreshold}MB`;
285
+ this.logger.error(error, 'JobExecutor', { jobId });
286
+ this.emit('memory:threshold-exceeded', {
287
+ jobId,
288
+ heapUsedMB,
289
+ threshold: this.options.memoryThreshold,
290
+ });
291
+ // Try to force GC if available
292
+ if (globalThis.gc) {
293
+ this.logger.warn('Forcing garbage collection', 'JobExecutor', { jobId });
294
+ globalThis.gc();
295
+ // Check again after GC
296
+ const newMemUsage = process.memoryUsage();
297
+ const newHeapUsedMB = newMemUsage.heapUsed / 1024 / 1024;
298
+ if (newHeapUsedMB > this.options.memoryThreshold) {
299
+ throw new Error(error);
300
+ }
301
+ this.logger.info('Memory recovered after GC', 'JobExecutor', {
302
+ before: Math.round(heapUsedMB),
303
+ after: Math.round(newHeapUsedMB),
304
+ });
305
+ }
306
+ else {
307
+ throw new Error(error);
308
+ }
309
+ }
310
+ }
311
+ /**
312
+ * Get current memory usage in MB
313
+ */
314
+ getMemoryUsage() {
315
+ const memUsage = process.memoryUsage();
316
+ return Math.round(memUsage.heapUsed / 1024 / 1024);
317
+ }
318
+ /**
319
+ * Cancel a running execution
320
+ */
321
+ cancelExecution(executionId) {
322
+ const controller = this.activeExecutions.get(executionId);
323
+ if (!controller) {
324
+ return false;
325
+ }
326
+ controller.abort();
327
+ this.logger.info(`Execution cancelled: ${executionId}`);
328
+ this.emit('execution:cancelled', { executionId });
329
+ return true;
330
+ }
331
+ /**
332
+ * Cancel all running executions
333
+ */
334
+ cancelAllExecutions() {
335
+ const executionIds = Array.from(this.activeExecutions.keys());
336
+ this.logger.info(`Cancelling ${executionIds.length} running executions`);
337
+ for (const executionId of executionIds) {
338
+ this.cancelExecution(executionId);
339
+ }
340
+ }
341
+ /**
342
+ * Get active execution count
343
+ */
344
+ getActiveExecutionCount() {
345
+ return this.activeExecutions.size;
346
+ }
347
+ /**
348
+ * Get circuit breaker status for job
349
+ */
350
+ getCircuitBreakerStatus(jobId) {
351
+ const breaker = this.circuitBreakers.get(jobId);
352
+ if (!breaker) {
353
+ return { exists: false };
354
+ }
355
+ return {
356
+ exists: true,
357
+ state: breaker.getState().toLowerCase(),
358
+ failures: breaker.getFailures(),
359
+ threshold: this.options.circuitBreakerThreshold,
360
+ };
361
+ }
362
+ /**
363
+ * Reset circuit breaker for job
364
+ */
365
+ resetCircuitBreaker(jobId) {
366
+ const breaker = this.circuitBreakers.get(jobId);
367
+ if (!breaker) {
368
+ return false;
369
+ }
370
+ breaker.reset();
371
+ this.logger.info(`Circuit breaker reset for job: ${jobId}`);
372
+ return true;
373
+ }
374
+ /**
375
+ * Update executor options at runtime
376
+ */
377
+ updateOptions(options) {
378
+ Object.assign(this.options, options);
379
+ this.logger.info('JobExecutor options updated', 'JobExecutor', { options });
380
+ }
381
+ /**
382
+ * Get current options
383
+ */
384
+ getOptions() {
385
+ return { ...this.options };
386
+ }
387
+ /**
388
+ * Shutdown and cleanup
389
+ */
390
+ async shutdown(gracePeriod = 30000) {
391
+ this.logger.info('JobExecutor shutting down...', 'JobExecutor', {
392
+ activeExecutions: this.activeExecutions.size,
393
+ gracePeriod,
394
+ });
395
+ this.isShuttingDown = true;
396
+ // Wait for active executions to complete or grace period to expire
397
+ const startTime = Date.now();
398
+ while (this.activeExecutions.size > 0 && Date.now() - startTime < gracePeriod) {
399
+ this.logger.debug(`Waiting for ${this.activeExecutions.size} active executions to complete`);
400
+ await this.sleep(1000);
401
+ }
402
+ // Force cancel remaining executions
403
+ if (this.activeExecutions.size > 0) {
404
+ this.logger.warn(`Force cancelling ${this.activeExecutions.size} remaining executions`);
405
+ this.cancelAllExecutions();
406
+ }
407
+ // Cleanup circuit breakers
408
+ this.circuitBreakers.clear();
409
+ this.removeAllListeners();
410
+ this.logger.info('JobExecutor shutdown complete');
411
+ }
412
+ }
413
+ //# sourceMappingURL=job-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job-executor.js","sourceRoot":"","sources":["../../../src/core/jobs/job-executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,214 @@
1
+ import { EventEmitter } from 'events';
2
+ import { Logger } from '../../types/logger.js';
3
+ import { JobExecution } from './job-state-manager.js';
4
+ import { LeaderElectionOptions } from './leader-election.js';
5
+ import { JobExecutorOptions, JobFunction } from './job-executor.js';
6
+ export type JobScheduleType = 'cron' | 'interval' | 'oneTime';
7
+ export interface JobSchedule {
8
+ type: JobScheduleType;
9
+ cron?: string;
10
+ interval?: number;
11
+ at?: Date;
12
+ }
13
+ export interface JobOptions {
14
+ name?: string;
15
+ schedule: JobSchedule;
16
+ enabled?: boolean;
17
+ priority?: number;
18
+ timezone?: string;
19
+ maxConcurrent?: number;
20
+ timeout?: number;
21
+ maxRetries?: number;
22
+ retryDelay?: number;
23
+ retryBackoff?: 'linear' | 'exponential';
24
+ enableCircuitBreaker?: boolean;
25
+ metadata?: Record<string, any>;
26
+ onStart?: (context: ExecutionContext) => void | Promise<void>;
27
+ onComplete?: (context: ExecutionContext, result: any) => void | Promise<void>;
28
+ onError?: (context: ExecutionContext, error: Error) => void | Promise<void>;
29
+ }
30
+ export interface ExecutionContext {
31
+ jobId: string;
32
+ executionId: string;
33
+ attempt: number;
34
+ startTime: Date;
35
+ metadata?: Record<string, any>;
36
+ }
37
+ export interface Job {
38
+ id: string;
39
+ name: string;
40
+ schedule: JobSchedule;
41
+ fn: JobFunction;
42
+ options: JobOptions;
43
+ nextRun?: Date;
44
+ enabled: boolean;
45
+ priority: number;
46
+ timer?: NodeJS.Timeout;
47
+ concurrentExecutions: number;
48
+ createdAt: Date;
49
+ }
50
+ export interface JobSchedulerOptions {
51
+ maxConcurrentJobs?: number;
52
+ enableLeaderElection?: boolean;
53
+ leaderElection?: LeaderElectionOptions;
54
+ executor?: JobExecutorOptions;
55
+ stateManager?: {
56
+ persistPath?: string;
57
+ historySize?: number;
58
+ persistInterval?: number;
59
+ enableAutoPersist?: boolean;
60
+ enableRecovery?: boolean;
61
+ };
62
+ gracefulShutdownTimeout?: number;
63
+ }
64
+ /**
65
+ * JobScheduler - Production-grade job scheduling system
66
+ * Features:
67
+ * - Cron, interval, and one-time scheduling
68
+ * - Leader election for distributed systems
69
+ * - Graceful shutdown with running job completion
70
+ * - Global and per-job concurrency control
71
+ * - Priority queue for job execution
72
+ * - Automatic crash recovery
73
+ * - Full observability with events and metrics
74
+ */
75
+ export declare class JobScheduler extends EventEmitter {
76
+ private jobs;
77
+ private stateManager;
78
+ private leaderElection?;
79
+ private executor;
80
+ private logger;
81
+ private loggerContext;
82
+ private started;
83
+ private isShuttingDown;
84
+ private maxConcurrentJobs;
85
+ private currentConcurrentJobs;
86
+ private pendingQueue;
87
+ private gracefulShutdownTimeout;
88
+ private enableLeaderElection;
89
+ constructor(logger: Logger, options?: JobSchedulerOptions);
90
+ /**
91
+ * Start the job scheduler
92
+ */
93
+ start(): Promise<void>;
94
+ /**
95
+ * Register a new job
96
+ */
97
+ registerJob(name: string, schedule: JobSchedule, fn: JobFunction, options?: Partial<JobOptions>): string;
98
+ /**
99
+ * Unregister a job
100
+ */
101
+ unregisterJob(jobId: string): boolean;
102
+ /**
103
+ * Get job by ID
104
+ */
105
+ getJob(jobId: string): Job | undefined;
106
+ /**
107
+ * Get all jobs
108
+ */
109
+ getAllJobs(): Job[];
110
+ /**
111
+ * Enable/disable job
112
+ */
113
+ setJobEnabled(jobId: string, enabled: boolean): boolean;
114
+ /**
115
+ * Manually trigger job execution
116
+ */
117
+ triggerJob(jobId: string, metadata?: Record<string, any>): Promise<ExecutionResult>;
118
+ /**
119
+ * Validate schedule configuration
120
+ */
121
+ private validateSchedule;
122
+ /**
123
+ * Calculate next run time for job
124
+ */
125
+ private calculateNextRun;
126
+ /**
127
+ * Schedule all jobs
128
+ */
129
+ private scheduleAllJobs;
130
+ /**
131
+ * Schedule a single job
132
+ */
133
+ private scheduleJob;
134
+ /**
135
+ * Unschedule a job
136
+ */
137
+ private unscheduleJob;
138
+ /**
139
+ * Unschedule all jobs
140
+ */
141
+ private unscheduleAllJobs;
142
+ /**
143
+ * Queue job for execution (with concurrency control)
144
+ */
145
+ private queueJobExecution;
146
+ /**
147
+ * Execute job asynchronously
148
+ */
149
+ private executeJobAsync;
150
+ /**
151
+ * Execute job with full lifecycle management
152
+ */
153
+ private executeJob;
154
+ /**
155
+ * Process pending queue
156
+ */
157
+ private processPendingQueue;
158
+ /**
159
+ * Check if this instance is the leader
160
+ */
161
+ private isLeader;
162
+ /**
163
+ * Generate unique job ID
164
+ */
165
+ private generateJobId;
166
+ /**
167
+ * Generate unique execution ID
168
+ */
169
+ private generateExecutionId;
170
+ /**
171
+ * Get scheduler stats
172
+ */
173
+ getStats(): {
174
+ totalJobs: number;
175
+ enabledJobs: number;
176
+ runningJobs: number;
177
+ queuedJobs: number;
178
+ isLeader: boolean;
179
+ isStarted: boolean;
180
+ };
181
+ /**
182
+ * Get job state
183
+ */
184
+ getJobState(jobId: string): import("./job-state-manager.js").JobState | undefined;
185
+ /**
186
+ * Get job history
187
+ */
188
+ getJobHistory(jobId: string, limit?: number): JobExecution[];
189
+ /**
190
+ * Get job metrics
191
+ */
192
+ getJobMetrics(jobId: string): {
193
+ successRate: number;
194
+ failureRate: number;
195
+ averageDuration: number;
196
+ totalExecutions: number;
197
+ recentFailures: number;
198
+ } | null;
199
+ /**
200
+ * Graceful shutdown
201
+ */
202
+ shutdown(): Promise<void>;
203
+ private sleep;
204
+ }
205
+ interface ExecutionResult {
206
+ success: boolean;
207
+ value?: any;
208
+ error?: Error;
209
+ attempts: number;
210
+ duration: number;
211
+ circuitBreakerTripped?: boolean;
212
+ timedOut?: boolean;
213
+ }
214
+ export {};