@morojs/moro 1.8.5 → 1.8.7
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 +7 -6
- package/dist/core/http/http-server.d.ts +5 -3
- package/dist/core/http/http-server.js +38 -11
- package/dist/core/http/http-server.js.map +1 -1
- package/dist/core/http/http2-server.d.ts +1 -1
- package/dist/core/http/http2-server.js +23 -9
- package/dist/core/http/http2-server.js.map +1 -1
- package/dist/core/http/moro-engine-server.d.ts +24 -4
- package/dist/core/http/moro-engine-server.js +194 -42
- package/dist/core/http/moro-engine-server.js.map +1 -1
- package/dist/core/jobs/job-executor.d.ts +1 -0
- package/dist/core/jobs/job-executor.js +23 -1
- package/dist/core/jobs/job-executor.js.map +1 -1
- package/dist/core/middleware/built-in/auth/helpers.js +11 -1
- package/dist/core/middleware/built-in/auth/helpers.js.map +1 -1
- package/dist/core/pooling/object-pool-manager.js +14 -20
- package/dist/core/pooling/object-pool-manager.js.map +1 -1
- package/dist/core/routing/radix-tree.d.ts +1 -0
- package/dist/core/routing/radix-tree.js +6 -1
- package/dist/core/routing/radix-tree.js.map +1 -1
- package/dist/core/routing/unified-router.js +33 -25
- package/dist/core/routing/unified-router.js.map +1 -1
- package/dist/core/utilities/hooks.d.ts +2 -0
- package/dist/core/utilities/hooks.js +28 -2
- package/dist/core/utilities/hooks.js.map +1 -1
- package/dist/moro.js +12 -0
- package/dist/moro.js.map +1 -1
- package/package.json +3 -1
|
@@ -27,6 +27,7 @@ export interface JobExecutorOptions {
|
|
|
27
27
|
circuitBreakerThreshold?: number;
|
|
28
28
|
circuitBreakerResetTimeout?: number;
|
|
29
29
|
enableMemoryMonitoring?: boolean;
|
|
30
|
+
/** Heap ceiling in MB. Defaults to 90% of the process's V8 heap limit. */
|
|
30
31
|
memoryThreshold?: number;
|
|
31
32
|
}
|
|
32
33
|
export interface JobFunction {
|
|
@@ -1,7 +1,29 @@
|
|
|
1
1
|
// Production-grade Job Executor
|
|
2
2
|
// Handles job execution with retry logic, timeout, circuit breaker, and memory monitoring
|
|
3
3
|
import { EventEmitter } from 'events';
|
|
4
|
+
import { getHeapStatistics } from 'v8';
|
|
4
5
|
import { CircuitBreaker } from '../utilities/circuit-breaker.js';
|
|
6
|
+
/**
|
|
7
|
+
* Default memory ceiling for job execution, in MB.
|
|
8
|
+
*
|
|
9
|
+
* Derived from the process's actual V8 heap limit rather than a fixed number.
|
|
10
|
+
* A hardcoded default (previously 512MB) is meaningless in isolation: 64-bit
|
|
11
|
+
* Node defaults to a ~4GB heap, so 512MB is only ~12% of what the process may
|
|
12
|
+
* legitimately use. Every job would refuse to run once the process crossed
|
|
13
|
+
* that line — and because heap usage rarely falls back, the failure was
|
|
14
|
+
* permanent rather than transient.
|
|
15
|
+
*
|
|
16
|
+
* 90% of the heap limit is the point where allocation pressure is real and
|
|
17
|
+
* refusing new work is the right call. An explicit `memoryThreshold` option
|
|
18
|
+
* still wins, so existing configuration is unaffected.
|
|
19
|
+
*/
|
|
20
|
+
function defaultMemoryThresholdMB() {
|
|
21
|
+
const limitMB = getHeapStatistics().heap_size_limit / 1024 / 1024;
|
|
22
|
+
// No floor: V8's own minimum heap is ~256MB, so any absolute floor would
|
|
23
|
+
// meet or exceed the limit in a memory-constrained container and disable
|
|
24
|
+
// the guard entirely. A percentage of the real limit is correct at any size.
|
|
25
|
+
return Math.round(limitMB * 0.9);
|
|
26
|
+
}
|
|
5
27
|
// Reference to global AbortController
|
|
6
28
|
const AbortControllerClass = globalThis.AbortController;
|
|
7
29
|
/**
|
|
@@ -34,7 +56,7 @@ export class JobExecutor extends EventEmitter {
|
|
|
34
56
|
circuitBreakerThreshold: options.circuitBreakerThreshold ?? 5,
|
|
35
57
|
circuitBreakerResetTimeout: options.circuitBreakerResetTimeout ?? 60000,
|
|
36
58
|
enableMemoryMonitoring: options.enableMemoryMonitoring ?? true,
|
|
37
|
-
memoryThreshold: options.memoryThreshold ??
|
|
59
|
+
memoryThreshold: options.memoryThreshold ?? defaultMemoryThresholdMB(),
|
|
38
60
|
};
|
|
39
61
|
this.logger.debug('JobExecutor initialized', 'JobExecutor', { options: this.options });
|
|
40
62
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"job-executor.js","sourceRoot":"","sources":["../../../src/core/jobs/job-executor.ts"],"names":[],"mappings":"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","sourcesContent":["// Production-grade Job Executor\n// Handles job execution with retry logic, timeout, circuit breaker, and memory monitoring\n\nimport { EventEmitter } from 'events';\nimport { Logger } from '../../types/logger.js';\nimport { CircuitBreaker } from '../utilities/circuit-breaker.js';\n\n// Type definitions for native Node.js AbortController (available in Node.js 15+)\ntype AbortSignal = {\n readonly aborted: boolean;\n addEventListener(type: 'abort', listener: () => void, options?: { once: boolean }): void;\n removeEventListener(type: 'abort', listener: () => void): void;\n};\n\ntype AbortController = {\n readonly signal: AbortSignal;\n abort(): void;\n};\n\n// Access global AbortController through globalThis\ndeclare global {\n interface GlobalThis {\n AbortController: new () => AbortController;\n }\n}\n\n// Reference to global AbortController\nconst AbortControllerClass = globalThis.AbortController;\n\nexport interface JobExecutorOptions {\n maxRetries?: number;\n retryDelay?: number;\n retryBackoff?: 'linear' | 'exponential';\n retryBackoffMultiplier?: number;\n maxRetryDelay?: number;\n timeout?: number;\n enableCircuitBreaker?: boolean;\n circuitBreakerThreshold?: number;\n circuitBreakerResetTimeout?: number;\n enableMemoryMonitoring?: boolean;\n memoryThreshold?: number; // MB\n}\n\nexport interface JobFunction {\n (...args: any[]): Promise<any> | any;\n}\n\nexport interface ExecutionContext {\n jobId: string;\n executionId: string;\n attempt: number;\n startTime: Date;\n metadata?: Record<string, any>;\n}\n\nexport interface ExecutionResult {\n success: boolean;\n value?: any;\n error?: Error | undefined;\n attempts: number;\n duration: number;\n memoryUsed?: number;\n circuitBreakerTripped?: boolean;\n timedOut?: boolean;\n}\n\n/**\n * JobExecutor - Executes jobs with production-grade resilience\n * Features:\n * - Configurable retry with exponential backoff + jitter\n * - Timeout enforcement\n * - Circuit breaker integration\n * - Memory leak detection\n * - Graceful cancellation\n */\nexport class JobExecutor extends EventEmitter {\n private options: Required<JobExecutorOptions>;\n private logger: Logger;\n private circuitBreakers = new Map<string, CircuitBreaker>();\n private activeExecutions = new Map<string, AbortController>();\n private isShuttingDown = false;\n\n constructor(logger: Logger, options: JobExecutorOptions = {}) {\n super();\n this.logger = logger;\n\n // Set defaults\n this.options = {\n maxRetries: options.maxRetries ?? 3,\n retryDelay: options.retryDelay ?? 1000,\n retryBackoff: options.retryBackoff ?? 'exponential',\n retryBackoffMultiplier: options.retryBackoffMultiplier ?? 2,\n maxRetryDelay: options.maxRetryDelay ?? 60000,\n timeout: options.timeout ?? 300000, // 5 minutes default\n enableCircuitBreaker: options.enableCircuitBreaker ?? true,\n circuitBreakerThreshold: options.circuitBreakerThreshold ?? 5,\n circuitBreakerResetTimeout: options.circuitBreakerResetTimeout ?? 60000,\n enableMemoryMonitoring: options.enableMemoryMonitoring ?? true,\n memoryThreshold: options.memoryThreshold ?? 512, // 512MB default\n };\n\n this.logger.debug('JobExecutor initialized', 'JobExecutor', { options: this.options });\n }\n\n /**\n * Execute a job with full resilience features\n *\n * @param jobId - Unique job identifier\n * @param executionId - Unique execution identifier\n * @param jobFn - The job function to execute\n * @param context - Execution context\n * @param optionOverrides - Per-execution option overrides (merged on top of constructor defaults)\n */\n public async execute(\n jobId: string,\n executionId: string,\n jobFn: JobFunction,\n context?: ExecutionContext,\n optionOverrides?: Partial<JobExecutorOptions>\n ): Promise<ExecutionResult> {\n if (this.isShuttingDown) {\n throw new Error('JobExecutor is shutting down');\n }\n\n // Merge per-execution overrides with constructor defaults\n const opts = optionOverrides ? { ...this.options, ...optionOverrides } : this.options;\n\n const ctx: ExecutionContext = context || {\n jobId,\n executionId,\n attempt: 1,\n startTime: new Date(),\n };\n\n const startTime = Date.now();\n const abortController = new AbortControllerClass();\n this.activeExecutions.set(executionId, abortController);\n\n let lastError: Error | undefined;\n let attempts = 0;\n let circuitBreakerTripped = false;\n let timedOut = false;\n\n try {\n // Check memory before execution\n if (opts.enableMemoryMonitoring) {\n await this.checkMemoryUsage(jobId);\n }\n\n // Execute with retries\n while (attempts <= opts.maxRetries) {\n attempts++;\n ctx.attempt = attempts;\n\n try {\n // Check circuit breaker\n if (opts.enableCircuitBreaker) {\n const breaker = this.getCircuitBreaker(jobId);\n\n if (breaker.isOpen()) {\n circuitBreakerTripped = true;\n throw new Error(`Circuit breaker open for job ${jobId}`);\n }\n }\n\n // Execute with timeout\n const result = await this.executeWithTimeout(\n jobFn,\n ctx,\n abortController.signal,\n opts.timeout\n );\n\n // Success - record in circuit breaker\n if (opts.enableCircuitBreaker) {\n const breaker = this.getCircuitBreaker(jobId);\n breaker.recordSuccess();\n }\n\n const duration = Date.now() - startTime;\n const memoryUsed = this.getMemoryUsage();\n\n this.logger.debug(`Job executed successfully: ${jobId}`, 'JobExecutor', {\n executionId,\n attempts,\n duration,\n memoryUsed,\n });\n\n this.emit('execution:success', {\n jobId,\n executionId,\n attempts,\n duration,\n memoryUsed,\n });\n\n return {\n success: true,\n value: result,\n attempts,\n duration,\n memoryUsed,\n circuitBreakerTripped: false,\n timedOut: false,\n };\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // Check if it's a timeout\n if (lastError.name === 'TimeoutError' || lastError.message.includes('timeout')) {\n timedOut = true;\n }\n\n // Record failure in circuit breaker\n if (opts.enableCircuitBreaker && !circuitBreakerTripped) {\n const breaker = this.getCircuitBreaker(jobId);\n breaker.recordFailure();\n }\n\n this.logger.warn(\n `Job execution failed: ${jobId} (attempt ${attempts}/${opts.maxRetries + 1})`,\n 'JobExecutor',\n {\n executionId,\n error: lastError.message,\n timedOut,\n circuitBreakerTripped,\n }\n );\n\n this.emit('execution:retry', {\n jobId,\n executionId,\n attempt: attempts,\n maxAttempts: opts.maxRetries + 1,\n error: lastError,\n timedOut,\n });\n\n // Don't retry if circuit breaker tripped or shutting down\n if (circuitBreakerTripped || this.isShuttingDown) {\n break;\n }\n\n // Calculate retry delay with backoff and jitter\n if (attempts <= opts.maxRetries) {\n const delay = this.calculateRetryDelay(attempts, opts);\n await this.sleep(delay);\n }\n }\n }\n\n // All retries exhausted\n const duration = Date.now() - startTime;\n\n this.logger.error(\n `Job execution failed after ${attempts} attempts: ${jobId}`,\n 'JobExecutor',\n {\n executionId,\n error: lastError?.message,\n timedOut,\n circuitBreakerTripped,\n }\n );\n\n this.emit('execution:failed', {\n jobId,\n executionId,\n attempts,\n duration,\n error: lastError,\n timedOut,\n circuitBreakerTripped,\n });\n\n return {\n success: false,\n error: lastError,\n attempts,\n duration,\n circuitBreakerTripped,\n timedOut,\n };\n } finally {\n this.activeExecutions.delete(executionId);\n\n // Force GC if memory threshold exceeded\n if (opts.enableMemoryMonitoring) {\n const memUsage = process.memoryUsage();\n const heapUsedMB = memUsage.heapUsed / 1024 / 1024;\n\n if (heapUsedMB > opts.memoryThreshold * 0.9 && globalThis.gc) {\n this.logger.warn('High memory usage detected, triggering GC', 'JobExecutor', {\n heapUsedMB: Math.round(heapUsedMB),\n threshold: opts.memoryThreshold,\n });\n globalThis.gc();\n }\n }\n }\n }\n\n /**\n * Execute job function with timeout\n */\n private async executeWithTimeout(\n jobFn: JobFunction,\n context: ExecutionContext,\n signal: AbortSignal,\n timeout?: number\n ): Promise<any> {\n const effectiveTimeout = timeout ?? this.options.timeout;\n return new Promise((resolve, reject) => {\n // Setup timeout\n const timeoutId = setTimeout(() => {\n const error = new Error(`Job execution timeout after ${effectiveTimeout}ms`);\n error.name = 'TimeoutError';\n reject(error);\n }, effectiveTimeout);\n\n // Don't keep process alive for job execution timeout\n timeoutId.unref();\n\n // Setup abort handler\n const abortHandler = () => {\n clearTimeout(timeoutId);\n reject(new Error('Job execution cancelled'));\n };\n\n if (signal.aborted) {\n clearTimeout(timeoutId);\n reject(new Error('Job execution cancelled'));\n return;\n }\n\n signal.addEventListener('abort', abortHandler, { once: true });\n\n // Execute job\n Promise.resolve()\n .then(() => jobFn(context))\n .then(result => {\n clearTimeout(timeoutId);\n signal.removeEventListener('abort', abortHandler);\n resolve(result);\n })\n .catch(error => {\n clearTimeout(timeoutId);\n signal.removeEventListener('abort', abortHandler);\n reject(error);\n });\n });\n }\n\n /**\n * Calculate retry delay with backoff and jitter\n */\n private calculateRetryDelay(\n attempt: number,\n opts?: Pick<\n Required<JobExecutorOptions>,\n 'retryBackoff' | 'retryDelay' | 'retryBackoffMultiplier' | 'maxRetryDelay'\n >\n ): number {\n const effectiveOpts = opts ?? this.options;\n let delay: number;\n\n if (effectiveOpts.retryBackoff === 'exponential') {\n delay =\n effectiveOpts.retryDelay * Math.pow(effectiveOpts.retryBackoffMultiplier, attempt - 1);\n } else {\n delay = effectiveOpts.retryDelay * attempt;\n }\n\n // Cap at max delay\n delay = Math.min(delay, effectiveOpts.maxRetryDelay);\n\n // Add jitter (±20%)\n const jitter = delay * 0.2 * (Math.random() * 2 - 1);\n delay = Math.max(0, delay + jitter);\n\n return Math.floor(delay);\n }\n\n /**\n * Sleep helper\n */\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => {\n const timer = setTimeout(resolve, ms);\n timer.unref(); // Don't keep process alive\n });\n }\n\n /**\n * Get or create circuit breaker for job\n */\n private getCircuitBreaker(jobId: string): CircuitBreaker {\n let breaker = this.circuitBreakers.get(jobId);\n\n if (!breaker) {\n breaker = new CircuitBreaker({\n failureThreshold: this.options.circuitBreakerThreshold,\n resetTimeout: this.options.circuitBreakerResetTimeout,\n });\n\n // Log circuit breaker state changes\n breaker.on('open', () => {\n this.logger.error(`Circuit breaker opened for job: ${jobId}`);\n this.emit('circuit-breaker:open', { jobId });\n });\n\n breaker.on('halfOpen', () => {\n this.logger.info(`Circuit breaker half-open for job: ${jobId}`);\n this.emit('circuit-breaker:half-open', { jobId });\n });\n\n breaker.on('closed', () => {\n this.logger.info(`Circuit breaker closed for job: ${jobId}`);\n this.emit('circuit-breaker:closed', { jobId });\n });\n\n this.circuitBreakers.set(jobId, breaker);\n }\n\n return breaker;\n }\n\n /**\n * Check memory usage before execution\n */\n private async checkMemoryUsage(jobId: string): Promise<void> {\n const memUsage = process.memoryUsage();\n const heapUsedMB = memUsage.heapUsed / 1024 / 1024;\n\n if (heapUsedMB > this.options.memoryThreshold) {\n const error = `Memory threshold exceeded: ${Math.round(heapUsedMB)}MB / ${this.options.memoryThreshold}MB`;\n this.logger.error(error, 'JobExecutor', { jobId });\n\n this.emit('memory:threshold-exceeded', {\n jobId,\n heapUsedMB,\n threshold: this.options.memoryThreshold,\n });\n\n // Try to force GC if available\n if (globalThis.gc) {\n this.logger.warn('Forcing garbage collection', 'JobExecutor', { jobId });\n globalThis.gc();\n\n // Check again after GC\n const newMemUsage = process.memoryUsage();\n const newHeapUsedMB = newMemUsage.heapUsed / 1024 / 1024;\n\n if (newHeapUsedMB > this.options.memoryThreshold) {\n throw new Error(error);\n }\n\n this.logger.info('Memory recovered after GC', 'JobExecutor', {\n before: Math.round(heapUsedMB),\n after: Math.round(newHeapUsedMB),\n });\n } else {\n throw new Error(error);\n }\n }\n }\n\n /**\n * Get current memory usage in MB\n */\n private getMemoryUsage(): number {\n const memUsage = process.memoryUsage();\n return Math.round(memUsage.heapUsed / 1024 / 1024);\n }\n\n /**\n * Cancel a running execution\n */\n public cancelExecution(executionId: string): boolean {\n const controller = this.activeExecutions.get(executionId);\n if (!controller) {\n return false;\n }\n\n controller.abort();\n this.logger.info(`Execution cancelled: ${executionId}`);\n this.emit('execution:cancelled', { executionId });\n\n return true;\n }\n\n /**\n * Cancel all running executions\n */\n public cancelAllExecutions(): void {\n const executionIds = Array.from(this.activeExecutions.keys());\n\n this.logger.info(`Cancelling ${executionIds.length} running executions`);\n\n for (const executionId of executionIds) {\n this.cancelExecution(executionId);\n }\n }\n\n /**\n * Get active execution count\n */\n public getActiveExecutionCount(): number {\n return this.activeExecutions.size;\n }\n\n /**\n * Get circuit breaker status for job\n */\n public getCircuitBreakerStatus(jobId: string): {\n exists: boolean;\n state?: string;\n failures?: number;\n threshold?: number;\n } {\n const breaker = this.circuitBreakers.get(jobId);\n\n if (!breaker) {\n return { exists: false };\n }\n\n return {\n exists: true,\n state: breaker.getState().toLowerCase(),\n failures: breaker.getFailures(),\n threshold: this.options.circuitBreakerThreshold,\n };\n }\n\n /**\n * Reset circuit breaker for job\n */\n public resetCircuitBreaker(jobId: string): boolean {\n const breaker = this.circuitBreakers.get(jobId);\n if (!breaker) {\n return false;\n }\n\n breaker.reset();\n this.logger.info(`Circuit breaker reset for job: ${jobId}`);\n return true;\n }\n\n /**\n * Update executor options at runtime\n */\n public updateOptions(options: Partial<JobExecutorOptions>): void {\n Object.assign(this.options, options);\n this.logger.info('JobExecutor options updated', 'JobExecutor', { options });\n }\n\n /**\n * Get current options\n */\n public getOptions(): Required<JobExecutorOptions> {\n return { ...this.options };\n }\n\n /**\n * Shutdown and cleanup\n */\n public async shutdown(gracePeriod: number = 30000): Promise<void> {\n this.logger.info('JobExecutor shutting down...', 'JobExecutor', {\n activeExecutions: this.activeExecutions.size,\n gracePeriod,\n });\n\n this.isShuttingDown = true;\n\n // Wait for active executions to complete or grace period to expire\n const startTime = Date.now();\n\n while (this.activeExecutions.size > 0 && Date.now() - startTime < gracePeriod) {\n this.logger.debug(`Waiting for ${this.activeExecutions.size} active executions to complete`);\n await this.sleep(1000);\n }\n\n // Force cancel remaining executions\n if (this.activeExecutions.size > 0) {\n this.logger.warn(`Force cancelling ${this.activeExecutions.size} remaining executions`);\n this.cancelAllExecutions();\n }\n\n // Cleanup state\n this.circuitBreakers.clear();\n this.activeExecutions.clear();\n\n this.removeAllListeners();\n this.logger.info('JobExecutor shutdown complete');\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"job-executor.js","sourceRoot":"","sources":["../../../src/core/jobs/job-executor.ts"],"names":[],"mappings":"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","sourcesContent":["// Production-grade Job Executor\n// Handles job execution with retry logic, timeout, circuit breaker, and memory monitoring\n\nimport { EventEmitter } from 'events';\nimport { getHeapStatistics } from 'v8';\nimport { Logger } from '../../types/logger.js';\nimport { CircuitBreaker } from '../utilities/circuit-breaker.js';\n\n/**\n * Default memory ceiling for job execution, in MB.\n *\n * Derived from the process's actual V8 heap limit rather than a fixed number.\n * A hardcoded default (previously 512MB) is meaningless in isolation: 64-bit\n * Node defaults to a ~4GB heap, so 512MB is only ~12% of what the process may\n * legitimately use. Every job would refuse to run once the process crossed\n * that line — and because heap usage rarely falls back, the failure was\n * permanent rather than transient.\n *\n * 90% of the heap limit is the point where allocation pressure is real and\n * refusing new work is the right call. An explicit `memoryThreshold` option\n * still wins, so existing configuration is unaffected.\n */\nfunction defaultMemoryThresholdMB(): number {\n const limitMB = getHeapStatistics().heap_size_limit / 1024 / 1024;\n // No floor: V8's own minimum heap is ~256MB, so any absolute floor would\n // meet or exceed the limit in a memory-constrained container and disable\n // the guard entirely. A percentage of the real limit is correct at any size.\n return Math.round(limitMB * 0.9);\n}\n\n// Type definitions for native Node.js AbortController (available in Node.js 15+)\ntype AbortSignal = {\n readonly aborted: boolean;\n addEventListener(type: 'abort', listener: () => void, options?: { once: boolean }): void;\n removeEventListener(type: 'abort', listener: () => void): void;\n};\n\ntype AbortController = {\n readonly signal: AbortSignal;\n abort(): void;\n};\n\n// Access global AbortController through globalThis\ndeclare global {\n interface GlobalThis {\n AbortController: new () => AbortController;\n }\n}\n\n// Reference to global AbortController\nconst AbortControllerClass = globalThis.AbortController;\n\nexport interface JobExecutorOptions {\n maxRetries?: number;\n retryDelay?: number;\n retryBackoff?: 'linear' | 'exponential';\n retryBackoffMultiplier?: number;\n maxRetryDelay?: number;\n timeout?: number;\n enableCircuitBreaker?: boolean;\n circuitBreakerThreshold?: number;\n circuitBreakerResetTimeout?: number;\n enableMemoryMonitoring?: boolean;\n /** Heap ceiling in MB. Defaults to 90% of the process's V8 heap limit. */\n memoryThreshold?: number;\n}\n\nexport interface JobFunction {\n (...args: any[]): Promise<any> | any;\n}\n\nexport interface ExecutionContext {\n jobId: string;\n executionId: string;\n attempt: number;\n startTime: Date;\n metadata?: Record<string, any>;\n}\n\nexport interface ExecutionResult {\n success: boolean;\n value?: any;\n error?: Error | undefined;\n attempts: number;\n duration: number;\n memoryUsed?: number;\n circuitBreakerTripped?: boolean;\n timedOut?: boolean;\n}\n\n/**\n * JobExecutor - Executes jobs with production-grade resilience\n * Features:\n * - Configurable retry with exponential backoff + jitter\n * - Timeout enforcement\n * - Circuit breaker integration\n * - Memory leak detection\n * - Graceful cancellation\n */\nexport class JobExecutor extends EventEmitter {\n private options: Required<JobExecutorOptions>;\n private logger: Logger;\n private circuitBreakers = new Map<string, CircuitBreaker>();\n private activeExecutions = new Map<string, AbortController>();\n private isShuttingDown = false;\n\n constructor(logger: Logger, options: JobExecutorOptions = {}) {\n super();\n this.logger = logger;\n\n // Set defaults\n this.options = {\n maxRetries: options.maxRetries ?? 3,\n retryDelay: options.retryDelay ?? 1000,\n retryBackoff: options.retryBackoff ?? 'exponential',\n retryBackoffMultiplier: options.retryBackoffMultiplier ?? 2,\n maxRetryDelay: options.maxRetryDelay ?? 60000,\n timeout: options.timeout ?? 300000, // 5 minutes default\n enableCircuitBreaker: options.enableCircuitBreaker ?? true,\n circuitBreakerThreshold: options.circuitBreakerThreshold ?? 5,\n circuitBreakerResetTimeout: options.circuitBreakerResetTimeout ?? 60000,\n enableMemoryMonitoring: options.enableMemoryMonitoring ?? true,\n memoryThreshold: options.memoryThreshold ?? defaultMemoryThresholdMB(),\n };\n\n this.logger.debug('JobExecutor initialized', 'JobExecutor', { options: this.options });\n }\n\n /**\n * Execute a job with full resilience features\n *\n * @param jobId - Unique job identifier\n * @param executionId - Unique execution identifier\n * @param jobFn - The job function to execute\n * @param context - Execution context\n * @param optionOverrides - Per-execution option overrides (merged on top of constructor defaults)\n */\n public async execute(\n jobId: string,\n executionId: string,\n jobFn: JobFunction,\n context?: ExecutionContext,\n optionOverrides?: Partial<JobExecutorOptions>\n ): Promise<ExecutionResult> {\n if (this.isShuttingDown) {\n throw new Error('JobExecutor is shutting down');\n }\n\n // Merge per-execution overrides with constructor defaults\n const opts = optionOverrides ? { ...this.options, ...optionOverrides } : this.options;\n\n const ctx: ExecutionContext = context || {\n jobId,\n executionId,\n attempt: 1,\n startTime: new Date(),\n };\n\n const startTime = Date.now();\n const abortController = new AbortControllerClass();\n this.activeExecutions.set(executionId, abortController);\n\n let lastError: Error | undefined;\n let attempts = 0;\n let circuitBreakerTripped = false;\n let timedOut = false;\n\n try {\n // Check memory before execution\n if (opts.enableMemoryMonitoring) {\n await this.checkMemoryUsage(jobId);\n }\n\n // Execute with retries\n while (attempts <= opts.maxRetries) {\n attempts++;\n ctx.attempt = attempts;\n\n try {\n // Check circuit breaker\n if (opts.enableCircuitBreaker) {\n const breaker = this.getCircuitBreaker(jobId);\n\n if (breaker.isOpen()) {\n circuitBreakerTripped = true;\n throw new Error(`Circuit breaker open for job ${jobId}`);\n }\n }\n\n // Execute with timeout\n const result = await this.executeWithTimeout(\n jobFn,\n ctx,\n abortController.signal,\n opts.timeout\n );\n\n // Success - record in circuit breaker\n if (opts.enableCircuitBreaker) {\n const breaker = this.getCircuitBreaker(jobId);\n breaker.recordSuccess();\n }\n\n const duration = Date.now() - startTime;\n const memoryUsed = this.getMemoryUsage();\n\n this.logger.debug(`Job executed successfully: ${jobId}`, 'JobExecutor', {\n executionId,\n attempts,\n duration,\n memoryUsed,\n });\n\n this.emit('execution:success', {\n jobId,\n executionId,\n attempts,\n duration,\n memoryUsed,\n });\n\n return {\n success: true,\n value: result,\n attempts,\n duration,\n memoryUsed,\n circuitBreakerTripped: false,\n timedOut: false,\n };\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // Check if it's a timeout\n if (lastError.name === 'TimeoutError' || lastError.message.includes('timeout')) {\n timedOut = true;\n }\n\n // Record failure in circuit breaker\n if (opts.enableCircuitBreaker && !circuitBreakerTripped) {\n const breaker = this.getCircuitBreaker(jobId);\n breaker.recordFailure();\n }\n\n this.logger.warn(\n `Job execution failed: ${jobId} (attempt ${attempts}/${opts.maxRetries + 1})`,\n 'JobExecutor',\n {\n executionId,\n error: lastError.message,\n timedOut,\n circuitBreakerTripped,\n }\n );\n\n this.emit('execution:retry', {\n jobId,\n executionId,\n attempt: attempts,\n maxAttempts: opts.maxRetries + 1,\n error: lastError,\n timedOut,\n });\n\n // Don't retry if circuit breaker tripped or shutting down\n if (circuitBreakerTripped || this.isShuttingDown) {\n break;\n }\n\n // Calculate retry delay with backoff and jitter\n if (attempts <= opts.maxRetries) {\n const delay = this.calculateRetryDelay(attempts, opts);\n await this.sleep(delay);\n }\n }\n }\n\n // All retries exhausted\n const duration = Date.now() - startTime;\n\n this.logger.error(\n `Job execution failed after ${attempts} attempts: ${jobId}`,\n 'JobExecutor',\n {\n executionId,\n error: lastError?.message,\n timedOut,\n circuitBreakerTripped,\n }\n );\n\n this.emit('execution:failed', {\n jobId,\n executionId,\n attempts,\n duration,\n error: lastError,\n timedOut,\n circuitBreakerTripped,\n });\n\n return {\n success: false,\n error: lastError,\n attempts,\n duration,\n circuitBreakerTripped,\n timedOut,\n };\n } finally {\n this.activeExecutions.delete(executionId);\n\n // Force GC if memory threshold exceeded\n if (opts.enableMemoryMonitoring) {\n const memUsage = process.memoryUsage();\n const heapUsedMB = memUsage.heapUsed / 1024 / 1024;\n\n if (heapUsedMB > opts.memoryThreshold * 0.9 && globalThis.gc) {\n this.logger.warn('High memory usage detected, triggering GC', 'JobExecutor', {\n heapUsedMB: Math.round(heapUsedMB),\n threshold: opts.memoryThreshold,\n });\n globalThis.gc();\n }\n }\n }\n }\n\n /**\n * Execute job function with timeout\n */\n private async executeWithTimeout(\n jobFn: JobFunction,\n context: ExecutionContext,\n signal: AbortSignal,\n timeout?: number\n ): Promise<any> {\n const effectiveTimeout = timeout ?? this.options.timeout;\n return new Promise((resolve, reject) => {\n // Setup timeout\n const timeoutId = setTimeout(() => {\n const error = new Error(`Job execution timeout after ${effectiveTimeout}ms`);\n error.name = 'TimeoutError';\n reject(error);\n }, effectiveTimeout);\n\n // Don't keep process alive for job execution timeout\n timeoutId.unref();\n\n // Setup abort handler\n const abortHandler = () => {\n clearTimeout(timeoutId);\n reject(new Error('Job execution cancelled'));\n };\n\n if (signal.aborted) {\n clearTimeout(timeoutId);\n reject(new Error('Job execution cancelled'));\n return;\n }\n\n signal.addEventListener('abort', abortHandler, { once: true });\n\n // Execute job\n Promise.resolve()\n .then(() => jobFn(context))\n .then(result => {\n clearTimeout(timeoutId);\n signal.removeEventListener('abort', abortHandler);\n resolve(result);\n })\n .catch(error => {\n clearTimeout(timeoutId);\n signal.removeEventListener('abort', abortHandler);\n reject(error);\n });\n });\n }\n\n /**\n * Calculate retry delay with backoff and jitter\n */\n private calculateRetryDelay(\n attempt: number,\n opts?: Pick<\n Required<JobExecutorOptions>,\n 'retryBackoff' | 'retryDelay' | 'retryBackoffMultiplier' | 'maxRetryDelay'\n >\n ): number {\n const effectiveOpts = opts ?? this.options;\n let delay: number;\n\n if (effectiveOpts.retryBackoff === 'exponential') {\n delay =\n effectiveOpts.retryDelay * Math.pow(effectiveOpts.retryBackoffMultiplier, attempt - 1);\n } else {\n delay = effectiveOpts.retryDelay * attempt;\n }\n\n // Cap at max delay\n delay = Math.min(delay, effectiveOpts.maxRetryDelay);\n\n // Add jitter (±20%)\n const jitter = delay * 0.2 * (Math.random() * 2 - 1);\n delay = Math.max(0, delay + jitter);\n\n return Math.floor(delay);\n }\n\n /**\n * Sleep helper\n */\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => {\n const timer = setTimeout(resolve, ms);\n timer.unref(); // Don't keep process alive\n });\n }\n\n /**\n * Get or create circuit breaker for job\n */\n private getCircuitBreaker(jobId: string): CircuitBreaker {\n let breaker = this.circuitBreakers.get(jobId);\n\n if (!breaker) {\n breaker = new CircuitBreaker({\n failureThreshold: this.options.circuitBreakerThreshold,\n resetTimeout: this.options.circuitBreakerResetTimeout,\n });\n\n // Log circuit breaker state changes\n breaker.on('open', () => {\n this.logger.error(`Circuit breaker opened for job: ${jobId}`);\n this.emit('circuit-breaker:open', { jobId });\n });\n\n breaker.on('halfOpen', () => {\n this.logger.info(`Circuit breaker half-open for job: ${jobId}`);\n this.emit('circuit-breaker:half-open', { jobId });\n });\n\n breaker.on('closed', () => {\n this.logger.info(`Circuit breaker closed for job: ${jobId}`);\n this.emit('circuit-breaker:closed', { jobId });\n });\n\n this.circuitBreakers.set(jobId, breaker);\n }\n\n return breaker;\n }\n\n /**\n * Check memory usage before execution\n */\n private async checkMemoryUsage(jobId: string): Promise<void> {\n const memUsage = process.memoryUsage();\n const heapUsedMB = memUsage.heapUsed / 1024 / 1024;\n\n if (heapUsedMB > this.options.memoryThreshold) {\n const error = `Memory threshold exceeded: ${Math.round(heapUsedMB)}MB / ${this.options.memoryThreshold}MB`;\n this.logger.error(error, 'JobExecutor', { jobId });\n\n this.emit('memory:threshold-exceeded', {\n jobId,\n heapUsedMB,\n threshold: this.options.memoryThreshold,\n });\n\n // Try to force GC if available\n if (globalThis.gc) {\n this.logger.warn('Forcing garbage collection', 'JobExecutor', { jobId });\n globalThis.gc();\n\n // Check again after GC\n const newMemUsage = process.memoryUsage();\n const newHeapUsedMB = newMemUsage.heapUsed / 1024 / 1024;\n\n if (newHeapUsedMB > this.options.memoryThreshold) {\n throw new Error(error);\n }\n\n this.logger.info('Memory recovered after GC', 'JobExecutor', {\n before: Math.round(heapUsedMB),\n after: Math.round(newHeapUsedMB),\n });\n } else {\n throw new Error(error);\n }\n }\n }\n\n /**\n * Get current memory usage in MB\n */\n private getMemoryUsage(): number {\n const memUsage = process.memoryUsage();\n return Math.round(memUsage.heapUsed / 1024 / 1024);\n }\n\n /**\n * Cancel a running execution\n */\n public cancelExecution(executionId: string): boolean {\n const controller = this.activeExecutions.get(executionId);\n if (!controller) {\n return false;\n }\n\n controller.abort();\n this.logger.info(`Execution cancelled: ${executionId}`);\n this.emit('execution:cancelled', { executionId });\n\n return true;\n }\n\n /**\n * Cancel all running executions\n */\n public cancelAllExecutions(): void {\n const executionIds = Array.from(this.activeExecutions.keys());\n\n this.logger.info(`Cancelling ${executionIds.length} running executions`);\n\n for (const executionId of executionIds) {\n this.cancelExecution(executionId);\n }\n }\n\n /**\n * Get active execution count\n */\n public getActiveExecutionCount(): number {\n return this.activeExecutions.size;\n }\n\n /**\n * Get circuit breaker status for job\n */\n public getCircuitBreakerStatus(jobId: string): {\n exists: boolean;\n state?: string;\n failures?: number;\n threshold?: number;\n } {\n const breaker = this.circuitBreakers.get(jobId);\n\n if (!breaker) {\n return { exists: false };\n }\n\n return {\n exists: true,\n state: breaker.getState().toLowerCase(),\n failures: breaker.getFailures(),\n threshold: this.options.circuitBreakerThreshold,\n };\n }\n\n /**\n * Reset circuit breaker for job\n */\n public resetCircuitBreaker(jobId: string): boolean {\n const breaker = this.circuitBreakers.get(jobId);\n if (!breaker) {\n return false;\n }\n\n breaker.reset();\n this.logger.info(`Circuit breaker reset for job: ${jobId}`);\n return true;\n }\n\n /**\n * Update executor options at runtime\n */\n public updateOptions(options: Partial<JobExecutorOptions>): void {\n Object.assign(this.options, options);\n this.logger.info('JobExecutor options updated', 'JobExecutor', { options });\n }\n\n /**\n * Get current options\n */\n public getOptions(): Required<JobExecutorOptions> {\n return { ...this.options };\n }\n\n /**\n * Shutdown and cleanup\n */\n public async shutdown(gracePeriod: number = 30000): Promise<void> {\n this.logger.info('JobExecutor shutting down...', 'JobExecutor', {\n activeExecutions: this.activeExecutions.size,\n gracePeriod,\n });\n\n this.isShuttingDown = true;\n\n // Wait for active executions to complete or grace period to expire\n const startTime = Date.now();\n\n while (this.activeExecutions.size > 0 && Date.now() - startTime < gracePeriod) {\n this.logger.debug(`Waiting for ${this.activeExecutions.size} active executions to complete`);\n await this.sleep(1000);\n }\n\n // Force cancel remaining executions\n if (this.activeExecutions.size > 0) {\n this.logger.warn(`Force cancelling ${this.activeExecutions.size} remaining executions`);\n this.cancelAllExecutions();\n }\n\n // Cleanup state\n this.circuitBreakers.clear();\n this.activeExecutions.clear();\n\n this.removeAllListeners();\n this.logger.info('JobExecutor shutdown complete');\n }\n}\n"]}
|
|
@@ -5,7 +5,17 @@ export function requireAuth(options = {}) {
|
|
|
5
5
|
return async (req, res, next) => {
|
|
6
6
|
const auth = req.auth;
|
|
7
7
|
if (!auth) {
|
|
8
|
-
|
|
8
|
+
// Server misconfiguration, not a client error. Throwing here surfaced as
|
|
9
|
+
// a generic "Internal server error" with no hint at the cause, which is
|
|
10
|
+
// a miserable first-run experience for anyone who declares .auth() on a
|
|
11
|
+
// route but forgets to install the middleware.
|
|
12
|
+
return res.status(500).json({
|
|
13
|
+
success: false,
|
|
14
|
+
error: 'Auth middleware not installed',
|
|
15
|
+
message: 'This route requires authentication, but no auth middleware is installed. ' +
|
|
16
|
+
'Add `app.use(auth({ ... }))` during setup before using .auth() on a route ' +
|
|
17
|
+
'or requireAuth() directly.',
|
|
18
|
+
});
|
|
9
19
|
}
|
|
10
20
|
// Check if already authenticated and should redirect
|
|
11
21
|
if (auth.isAuthenticated && options.redirectOnAuth) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../../../src/core/middleware/built-in/auth/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["// Auth Helper Middleware and Utilities\nimport { AuthRequest } from '../../../../types/auth.js';\n\nexport interface AuthGuardOptions {\n redirectTo?: string;\n redirectOnAuth?: string; // Redirect if already authenticated\n authorize?: (user: any) => boolean | Promise<boolean>;\n roles?: string[];\n permissions?: string[];\n allowUnauthenticated?: boolean;\n onUnauthorized?: (req: any, res: any) => void;\n onForbidden?: (req: any, res: any) => void;\n}\n\nexport interface AuthRouteOptions {\n requireAuth?: boolean;\n roles?: string[];\n permissions?: string[];\n redirectTo?: string;\n}\n\n/**\n * Auth Guard Middleware - Protects routes with authentication and authorization\n */\nexport function requireAuth(options: AuthGuardOptions = {}) {\n return async (req: any, res: any, next: any) => {\n const auth: AuthRequest = req.auth;\n\n if (!auth) {\n throw new Error('Auth middleware must be installed before using requireAuth');\n }\n\n // Check if already authenticated and should redirect\n if (auth.isAuthenticated && options.redirectOnAuth) {\n return res.redirect(options.redirectOnAuth);\n }\n\n // Check authentication requirement\n if (!options.allowUnauthenticated && !auth.isAuthenticated) {\n if (options.onUnauthorized) {\n return options.onUnauthorized(req, res);\n }\n\n if (options.redirectTo) {\n return res.redirect(`${options.redirectTo}?callbackUrl=${encodeURIComponent(req.url)}`);\n }\n\n return res.status(401).json({\n error: 'Authentication required',\n message: 'You must be logged in to access this resource',\n signInUrl: '/api/auth/signin',\n });\n }\n\n // Skip further checks if not authenticated but allowed\n if (!auth.isAuthenticated && options.allowUnauthenticated) {\n return next();\n }\n\n const user = auth.user;\n\n // Check roles if specified\n if (options.roles && options.roles.length > 0) {\n const userRoles = user?.roles || [];\n const hasRole = options.roles.some(role => userRoles.includes(role));\n\n if (!hasRole) {\n if (options.onForbidden) {\n return options.onForbidden(req, res);\n }\n\n return res.status(403).json({\n error: 'Insufficient permissions',\n message: `Required roles: ${options.roles.join(', ')}`,\n userRoles,\n });\n }\n }\n\n // Check permissions if specified\n if (options.permissions && options.permissions.length > 0) {\n const userPermissions = user?.permissions || [];\n const hasPermission = options.permissions.every(permission =>\n userPermissions.includes(permission)\n );\n\n if (!hasPermission) {\n if (options.onForbidden) {\n return options.onForbidden(req, res);\n }\n\n return res.status(403).json({\n error: 'Insufficient permissions',\n message: `Required permissions: ${options.permissions.join(', ')}`,\n userPermissions,\n });\n }\n }\n\n // Custom authorization function\n if (options.authorize) {\n try {\n const authorized = await options.authorize(user);\n\n if (!authorized) {\n if (options.onForbidden) {\n return options.onForbidden(req, res);\n }\n\n return res.status(403).json({\n error: 'Access denied',\n message: 'Custom authorization check failed',\n });\n }\n } catch {\n return res.status(500).json({\n error: 'Authorization error',\n message: 'Failed to verify authorization',\n });\n }\n }\n\n // All checks passed\n next();\n };\n}\n\n/**\n * Role-based access control middleware\n */\nexport function requireRole(\n role: string | string[],\n options: Omit<AuthGuardOptions, 'roles'> = {}\n) {\n const roles = Array.isArray(role) ? role : [role];\n return requireAuth({ ...options, roles });\n}\n\n/**\n * Permission-based access control middleware\n */\nexport function requirePermission(\n permission: string | string[],\n options: Omit<AuthGuardOptions, 'permissions'> = {}\n) {\n const permissions = Array.isArray(permission) ? permission : [permission];\n return requireAuth({ ...options, permissions });\n}\n\n/**\n * Admin-only access middleware\n */\nexport function requireAdmin(options: Omit<AuthGuardOptions, 'roles'> = {}) {\n return requireRole('admin', options);\n}\n\n/**\n * Guest-only middleware (redirect if authenticated)\n */\nexport function guestOnly(redirectTo = '/dashboard') {\n return requireAuth({\n allowUnauthenticated: true,\n redirectOnAuth: redirectTo,\n });\n}\n\n/**\n * Optional auth middleware (allows both authenticated and unauthenticated)\n */\nexport function optionalAuth() {\n return requireAuth({\n allowUnauthenticated: true,\n });\n}\n\n/**\n * Route-level auth decorator\n */\nexport function withAuth(options: AuthRouteOptions = {}) {\n return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n const originalMethod = descriptor.value;\n\n descriptor.value = async function (req: any, res: any, next: any) {\n if (options.requireAuth !== false) {\n const authMiddleware = requireAuth({\n ...(options.roles !== undefined ? { roles: options.roles } : {}),\n ...(options.redirectTo !== undefined ? { redirectTo: options.redirectTo } : {}),\n });\n\n await new Promise<void>((resolve, reject) => {\n void authMiddleware(req, res, (error: any) => {\n if (error) reject(error);\n else resolve();\n });\n });\n }\n\n return originalMethod.call(this, req, res, next);\n };\n\n return descriptor;\n };\n}\n\n/**\n * Auth utilities for manual checks in route handlers\n */\nexport const authUtils = {\n /**\n * Check if user is authenticated\n */\n isAuthenticated(req: any): boolean {\n return req.auth?.isAuthenticated || false;\n },\n\n /**\n * Get current user\n */\n getUser(req: any) {\n return req.auth?.user || null;\n },\n\n /**\n * Check if user has role\n */\n hasRole(req: any, role: string | string[]): boolean {\n const user = this.getUser(req);\n if (!user?.roles) return false;\n\n const roles = Array.isArray(role) ? role : [role];\n return roles.some(r => user.roles.includes(r));\n },\n\n /**\n * Check if user has permission\n */\n hasPermission(req: any, permission: string | string[]): boolean {\n const user = this.getUser(req);\n if (!user?.permissions) return false;\n\n const permissions = Array.isArray(permission) ? permission : [permission];\n return permissions.every(p => user.permissions.includes(p));\n },\n\n /**\n * Check if user is admin\n */\n isAdmin(req: any): boolean {\n return this.hasRole(req, 'admin');\n },\n\n /**\n * Get user ID\n */\n getUserId(req: any): string | null {\n return this.getUser(req)?.id || null;\n },\n\n /**\n * Force authentication check and redirect if needed\n */\n ensureAuth(req: any, res: any, redirectTo = '/api/auth/signin'): boolean {\n if (!this.isAuthenticated(req)) {\n res.redirect(`${redirectTo}?callbackUrl=${encodeURIComponent(req.url)}`);\n return false;\n }\n return true;\n },\n\n /**\n * Create auth response for API endpoints\n */\n createAuthResponse(req: any) {\n const auth = req.auth;\n\n return {\n isAuthenticated: auth?.isAuthenticated || false,\n user: auth?.user || null,\n session: auth?.session || null,\n timestamp: new Date().toISOString(),\n };\n },\n};\n\n/**\n * API Response helpers for auth endpoints\n */\nexport const authResponses = {\n unauthorized: (res: any, message = 'Authentication required') => {\n return res.status(401).json({\n error: 'Unauthorized',\n message,\n code: 'AUTH_REQUIRED',\n signInUrl: '/api/auth/signin',\n });\n },\n\n forbidden: (res: any, message = 'Insufficient permissions') => {\n return res.status(403).json({\n error: 'Forbidden',\n message,\n code: 'INSUFFICIENT_PERMISSIONS',\n });\n },\n\n authSuccess: (res: any, user: any, message = 'Authentication successful') => {\n return res.json({\n success: true,\n message,\n user: {\n id: user.id,\n name: user.name,\n email: user.email,\n roles: user.roles || [],\n permissions: user.permissions || [],\n },\n });\n },\n\n authError: (res: any, error: string, message = 'Authentication failed') => {\n return res.status(400).json({\n error,\n message,\n code: 'AUTH_ERROR',\n });\n },\n};\n\n/**\n * Higher-order function to create protected route handlers\n */\nexport function protectedRoute(\n handler: (req: any, res: any, next?: any) => any,\n options: AuthGuardOptions = {}\n) {\n return async (req: any, res: any, next: any) => {\n const authMiddleware = requireAuth(options);\n\n return new Promise<void>((resolve, reject) => {\n void authMiddleware(req, res, (error: any) => {\n if (error) {\n reject(error);\n } else {\n Promise.resolve(handler(req, res, next))\n .then(() => resolve())\n .catch(reject);\n }\n });\n });\n };\n}\n\n/**\n * Session management helpers\n */\nexport const sessionHelpers = {\n /**\n * Store data in session\n */\n async setSessionData(req: any, key: string, value: any) {\n if (req.session) {\n req.session[key] = value;\n await req.session.save();\n }\n },\n\n /**\n * Get data from session\n */\n getSessionData(req: any, key: string) {\n return req.session?.[key] || null;\n },\n\n /**\n * Remove data from session\n */\n async removeSessionData(req: any, key: string) {\n if (req.session && key in req.session.data) {\n delete req.session.data[key];\n await req.session.save();\n }\n },\n\n /**\n * Clear entire session\n */\n async clearSession(req: any) {\n if (req.session) {\n await req.session.destroy();\n }\n },\n\n /**\n * Regenerate session ID\n */\n async regenerateSession(req: any) {\n if (req.session) {\n return await req.session.regenerate();\n }\n },\n};\n"]}
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../../../src/core/middleware/built-in/auth/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["// Auth Helper Middleware and Utilities\nimport { AuthRequest } from '../../../../types/auth.js';\n\nexport interface AuthGuardOptions {\n redirectTo?: string;\n redirectOnAuth?: string; // Redirect if already authenticated\n authorize?: (user: any) => boolean | Promise<boolean>;\n roles?: string[];\n permissions?: string[];\n allowUnauthenticated?: boolean;\n onUnauthorized?: (req: any, res: any) => void;\n onForbidden?: (req: any, res: any) => void;\n}\n\nexport interface AuthRouteOptions {\n requireAuth?: boolean;\n roles?: string[];\n permissions?: string[];\n redirectTo?: string;\n}\n\n/**\n * Auth Guard Middleware - Protects routes with authentication and authorization\n */\nexport function requireAuth(options: AuthGuardOptions = {}) {\n return async (req: any, res: any, next: any) => {\n const auth: AuthRequest = req.auth;\n\n if (!auth) {\n // Server misconfiguration, not a client error. Throwing here surfaced as\n // a generic \"Internal server error\" with no hint at the cause, which is\n // a miserable first-run experience for anyone who declares .auth() on a\n // route but forgets to install the middleware.\n return res.status(500).json({\n success: false,\n error: 'Auth middleware not installed',\n message:\n 'This route requires authentication, but no auth middleware is installed. ' +\n 'Add `app.use(auth({ ... }))` during setup before using .auth() on a route ' +\n 'or requireAuth() directly.',\n });\n }\n\n // Check if already authenticated and should redirect\n if (auth.isAuthenticated && options.redirectOnAuth) {\n return res.redirect(options.redirectOnAuth);\n }\n\n // Check authentication requirement\n if (!options.allowUnauthenticated && !auth.isAuthenticated) {\n if (options.onUnauthorized) {\n return options.onUnauthorized(req, res);\n }\n\n if (options.redirectTo) {\n return res.redirect(`${options.redirectTo}?callbackUrl=${encodeURIComponent(req.url)}`);\n }\n\n return res.status(401).json({\n error: 'Authentication required',\n message: 'You must be logged in to access this resource',\n signInUrl: '/api/auth/signin',\n });\n }\n\n // Skip further checks if not authenticated but allowed\n if (!auth.isAuthenticated && options.allowUnauthenticated) {\n return next();\n }\n\n const user = auth.user;\n\n // Check roles if specified\n if (options.roles && options.roles.length > 0) {\n const userRoles = user?.roles || [];\n const hasRole = options.roles.some(role => userRoles.includes(role));\n\n if (!hasRole) {\n if (options.onForbidden) {\n return options.onForbidden(req, res);\n }\n\n return res.status(403).json({\n error: 'Insufficient permissions',\n message: `Required roles: ${options.roles.join(', ')}`,\n userRoles,\n });\n }\n }\n\n // Check permissions if specified\n if (options.permissions && options.permissions.length > 0) {\n const userPermissions = user?.permissions || [];\n const hasPermission = options.permissions.every(permission =>\n userPermissions.includes(permission)\n );\n\n if (!hasPermission) {\n if (options.onForbidden) {\n return options.onForbidden(req, res);\n }\n\n return res.status(403).json({\n error: 'Insufficient permissions',\n message: `Required permissions: ${options.permissions.join(', ')}`,\n userPermissions,\n });\n }\n }\n\n // Custom authorization function\n if (options.authorize) {\n try {\n const authorized = await options.authorize(user);\n\n if (!authorized) {\n if (options.onForbidden) {\n return options.onForbidden(req, res);\n }\n\n return res.status(403).json({\n error: 'Access denied',\n message: 'Custom authorization check failed',\n });\n }\n } catch {\n return res.status(500).json({\n error: 'Authorization error',\n message: 'Failed to verify authorization',\n });\n }\n }\n\n // All checks passed\n next();\n };\n}\n\n/**\n * Role-based access control middleware\n */\nexport function requireRole(\n role: string | string[],\n options: Omit<AuthGuardOptions, 'roles'> = {}\n) {\n const roles = Array.isArray(role) ? role : [role];\n return requireAuth({ ...options, roles });\n}\n\n/**\n * Permission-based access control middleware\n */\nexport function requirePermission(\n permission: string | string[],\n options: Omit<AuthGuardOptions, 'permissions'> = {}\n) {\n const permissions = Array.isArray(permission) ? permission : [permission];\n return requireAuth({ ...options, permissions });\n}\n\n/**\n * Admin-only access middleware\n */\nexport function requireAdmin(options: Omit<AuthGuardOptions, 'roles'> = {}) {\n return requireRole('admin', options);\n}\n\n/**\n * Guest-only middleware (redirect if authenticated)\n */\nexport function guestOnly(redirectTo = '/dashboard') {\n return requireAuth({\n allowUnauthenticated: true,\n redirectOnAuth: redirectTo,\n });\n}\n\n/**\n * Optional auth middleware (allows both authenticated and unauthenticated)\n */\nexport function optionalAuth() {\n return requireAuth({\n allowUnauthenticated: true,\n });\n}\n\n/**\n * Route-level auth decorator\n */\nexport function withAuth(options: AuthRouteOptions = {}) {\n return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n const originalMethod = descriptor.value;\n\n descriptor.value = async function (req: any, res: any, next: any) {\n if (options.requireAuth !== false) {\n const authMiddleware = requireAuth({\n ...(options.roles !== undefined ? { roles: options.roles } : {}),\n ...(options.redirectTo !== undefined ? { redirectTo: options.redirectTo } : {}),\n });\n\n await new Promise<void>((resolve, reject) => {\n void authMiddleware(req, res, (error: any) => {\n if (error) reject(error);\n else resolve();\n });\n });\n }\n\n return originalMethod.call(this, req, res, next);\n };\n\n return descriptor;\n };\n}\n\n/**\n * Auth utilities for manual checks in route handlers\n */\nexport const authUtils = {\n /**\n * Check if user is authenticated\n */\n isAuthenticated(req: any): boolean {\n return req.auth?.isAuthenticated || false;\n },\n\n /**\n * Get current user\n */\n getUser(req: any) {\n return req.auth?.user || null;\n },\n\n /**\n * Check if user has role\n */\n hasRole(req: any, role: string | string[]): boolean {\n const user = this.getUser(req);\n if (!user?.roles) return false;\n\n const roles = Array.isArray(role) ? role : [role];\n return roles.some(r => user.roles.includes(r));\n },\n\n /**\n * Check if user has permission\n */\n hasPermission(req: any, permission: string | string[]): boolean {\n const user = this.getUser(req);\n if (!user?.permissions) return false;\n\n const permissions = Array.isArray(permission) ? permission : [permission];\n return permissions.every(p => user.permissions.includes(p));\n },\n\n /**\n * Check if user is admin\n */\n isAdmin(req: any): boolean {\n return this.hasRole(req, 'admin');\n },\n\n /**\n * Get user ID\n */\n getUserId(req: any): string | null {\n return this.getUser(req)?.id || null;\n },\n\n /**\n * Force authentication check and redirect if needed\n */\n ensureAuth(req: any, res: any, redirectTo = '/api/auth/signin'): boolean {\n if (!this.isAuthenticated(req)) {\n res.redirect(`${redirectTo}?callbackUrl=${encodeURIComponent(req.url)}`);\n return false;\n }\n return true;\n },\n\n /**\n * Create auth response for API endpoints\n */\n createAuthResponse(req: any) {\n const auth = req.auth;\n\n return {\n isAuthenticated: auth?.isAuthenticated || false,\n user: auth?.user || null,\n session: auth?.session || null,\n timestamp: new Date().toISOString(),\n };\n },\n};\n\n/**\n * API Response helpers for auth endpoints\n */\nexport const authResponses = {\n unauthorized: (res: any, message = 'Authentication required') => {\n return res.status(401).json({\n error: 'Unauthorized',\n message,\n code: 'AUTH_REQUIRED',\n signInUrl: '/api/auth/signin',\n });\n },\n\n forbidden: (res: any, message = 'Insufficient permissions') => {\n return res.status(403).json({\n error: 'Forbidden',\n message,\n code: 'INSUFFICIENT_PERMISSIONS',\n });\n },\n\n authSuccess: (res: any, user: any, message = 'Authentication successful') => {\n return res.json({\n success: true,\n message,\n user: {\n id: user.id,\n name: user.name,\n email: user.email,\n roles: user.roles || [],\n permissions: user.permissions || [],\n },\n });\n },\n\n authError: (res: any, error: string, message = 'Authentication failed') => {\n return res.status(400).json({\n error,\n message,\n code: 'AUTH_ERROR',\n });\n },\n};\n\n/**\n * Higher-order function to create protected route handlers\n */\nexport function protectedRoute(\n handler: (req: any, res: any, next?: any) => any,\n options: AuthGuardOptions = {}\n) {\n return async (req: any, res: any, next: any) => {\n const authMiddleware = requireAuth(options);\n\n return new Promise<void>((resolve, reject) => {\n void authMiddleware(req, res, (error: any) => {\n if (error) {\n reject(error);\n } else {\n Promise.resolve(handler(req, res, next))\n .then(() => resolve())\n .catch(reject);\n }\n });\n });\n };\n}\n\n/**\n * Session management helpers\n */\nexport const sessionHelpers = {\n /**\n * Store data in session\n */\n async setSessionData(req: any, key: string, value: any) {\n if (req.session) {\n req.session[key] = value;\n await req.session.save();\n }\n },\n\n /**\n * Get data from session\n */\n getSessionData(req: any, key: string) {\n return req.session?.[key] || null;\n },\n\n /**\n * Remove data from session\n */\n async removeSessionData(req: any, key: string) {\n if (req.session && key in req.session.data) {\n delete req.session.data[key];\n await req.session.save();\n }\n },\n\n /**\n * Clear entire session\n */\n async clearSession(req: any) {\n if (req.session) {\n await req.session.destroy();\n }\n },\n\n /**\n * Regenerate session ID\n */\n async regenerateSession(req: any) {\n if (req.session) {\n return await req.session.regenerate();\n }\n },\n};\n"]}
|
|
@@ -91,21 +91,19 @@ export class ObjectPoolManager {
|
|
|
91
91
|
const paramSize = sizes?.params ?? 50; // More aggressive default
|
|
92
92
|
const querySize = sizes?.query ?? 50;
|
|
93
93
|
const headerSize = sizes?.headers ?? 10;
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
this.headerPool.release(obj);
|
|
108
|
-
}
|
|
94
|
+
// Acquire the full batch before releasing: an acquire immediately after a
|
|
95
|
+
// release just pops the object that was pushed, so an interleaved loop
|
|
96
|
+
// creates one object no matter the count
|
|
97
|
+
const warm = (pool, count) => {
|
|
98
|
+
const objs = new Array(count);
|
|
99
|
+
for (let i = 0; i < count; i++)
|
|
100
|
+
objs[i] = pool.acquire();
|
|
101
|
+
for (let i = 0; i < count; i++)
|
|
102
|
+
pool.release(objs[i]);
|
|
103
|
+
};
|
|
104
|
+
warm(this.paramPool, paramSize);
|
|
105
|
+
warm(this.queryPool, querySize);
|
|
106
|
+
warm(this.headerPool, headerSize);
|
|
109
107
|
// Pre-warm buffer pools with configurable sizes
|
|
110
108
|
const bufferSizes = sizes?.buffers ?? {};
|
|
111
109
|
const bufferSizesLen = this.bufferSizes.length;
|
|
@@ -115,11 +113,7 @@ export class ObjectPoolManager {
|
|
|
115
113
|
continue;
|
|
116
114
|
const pool = this.bufferPools.get(size);
|
|
117
115
|
if (pool) {
|
|
118
|
-
|
|
119
|
-
for (let j = 0; j < warmCount; j++) {
|
|
120
|
-
const buffer = pool.acquire();
|
|
121
|
-
pool.release(buffer);
|
|
122
|
-
}
|
|
116
|
+
warm(pool, bufferSizes[size] ?? Math.min(25, pool.stats.maxSize));
|
|
123
117
|
}
|
|
124
118
|
}
|
|
125
119
|
logger.debug('Object pools pre-warmed with optimal sizes', 'PoolManager', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object-pool-manager.js","sourceRoot":"","sources":["../../../src/core/pooling/object-pool-manager.ts"],"names":[],"mappings":"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","sourcesContent":["// Unified Object Pool Manager\n// Consolidates object pooling from http-server, router, and other components\n\nimport { createFrameworkLogger } from '../logger/index.js';\nimport * as crypto from 'crypto';\nimport { ObjectPool } from './object-pool.js';\nimport { LRUCache } from './lru-cache.js';\nconst logger = createFrameworkLogger('ObjectPoolManager');\n\n/**\n * ObjectPoolManager - Singleton for managing all object pools\n * Consolidates pools from:\n * - MoroHttpServer (paramObjectPool, bufferPool)\n * - Router (paramObjectPool)\n * - Various route caches\n */\nexport class ObjectPoolManager {\n private static instance: ObjectPoolManager | null = null;\n\n // Parameter object pool (for route params)\n private paramPool: ObjectPool<Record<string, string>>;\n\n // Header object pool (for parsed headers)\n private headerPool: ObjectPool<Record<string, string>>;\n\n // Query object pool (for parsed query strings)\n private queryPool: ObjectPool<Record<string, string>>;\n\n // Buffer pools by size\n private bufferPools: Map<number, ObjectPool<Buffer>>;\n private readonly bufferSizes = [64, 256, 1024, 4096, 16384];\n\n // Route lookup cache\n private routeCache: LRUCache<string, any>;\n\n // Response cache (for common responses - now includes full response metadata)\n private responseCache: LRUCache<\n string,\n { buffer: Buffer; headers: Record<string, string>; statusCode: number }\n >;\n\n // Performance monitoring\n private performanceStats = {\n poolHits: 0,\n poolMisses: 0,\n totalAcquisitions: 0,\n totalReleases: 0,\n lastAdjustment: 0,\n adjustmentInterval: 60000, // 1 minute\n };\n\n // Adaptive pool sizing\n private poolUsageHistory: Map<string, number[]> = new Map();\n private adaptiveMode = true;\n\n private constructor() {\n // Set initial last adjustment time to prevent immediate adjustment\n this.performanceStats.lastAdjustment = Date.now();\n\n // Initialize parameter object pool with adaptive sizing\n this.paramPool = new ObjectPool(\n () => ({}),\n 100, // Initial size\n (obj: Record<string, string>) => {\n // Clear all properties\n for (const key in obj) {\n delete obj[key];\n }\n }\n );\n\n // Initialize header object pool\n this.headerPool = new ObjectPool(\n () => ({}),\n 50, // Initial size - headers are less common to pool\n (obj: Record<string, string>) => {\n // Clear all properties\n for (const key in obj) {\n delete obj[key];\n }\n }\n );\n\n // Initialize query object pool\n this.queryPool = new ObjectPool(\n () => ({}),\n 100, // Initial size - queries are very common\n (obj: Record<string, string>) => {\n // Clear all properties\n for (const key in obj) {\n delete obj[key];\n }\n }\n );\n\n // Initialize buffer pools with enhanced sizing\n this.bufferPools = new Map();\n const bufferSizesLen = this.bufferSizes.length;\n for (let i = 0; i < bufferSizesLen; i++) {\n const size = this.bufferSizes[i];\n if (size === undefined) continue;\n this.bufferPools.set(\n size,\n new ObjectPool<Buffer>(() => Buffer.allocUnsafe(size), this.getOptimalPoolSize(size))\n );\n }\n\n // Initialize caches with enhanced statistics\n this.routeCache = new LRUCache(500);\n this.responseCache = new LRUCache(200); // Increased for full response caching\n\n // Pre-warm pools with optimal defaults\n this.preWarmPools();\n\n logger.debug(\n 'ObjectPoolManager initialized with enhanced performance features',\n 'Initialization'\n );\n }\n\n /**\n * Pre-warm pools with optimal sizes for better startup performance\n * Can be called with custom sizes to override defaults\n */\n preWarmPools(sizes?: {\n params?: number;\n query?: number;\n headers?: number;\n buffers?: Record<number, number>;\n }): void {\n // Aggressive pre-warming for common scenarios\n const paramSize = sizes?.params ?? 50; // More aggressive default\n const querySize = sizes?.query ?? 50;\n const headerSize = sizes?.headers ?? 10;\n\n // Pre-warm parameter pool\n for (let i = 0; i < paramSize; i++) {\n const obj = this.paramPool.acquire();\n this.paramPool.release(obj);\n }\n\n // Pre-warm query pool\n for (let i = 0; i < querySize; i++) {\n const obj = this.queryPool.acquire();\n this.queryPool.release(obj);\n }\n\n // Pre-warm header pool\n for (let i = 0; i < headerSize; i++) {\n const obj = this.headerPool.acquire();\n this.headerPool.release(obj);\n }\n\n // Pre-warm buffer pools with configurable sizes\n const bufferSizes = sizes?.buffers ?? {};\n const bufferSizesLen = this.bufferSizes.length;\n for (let i = 0; i < bufferSizesLen; i++) {\n const size = this.bufferSizes[i];\n if (size === undefined) continue;\n const pool = this.bufferPools.get(size);\n if (pool) {\n const warmCount = bufferSizes[size] ?? Math.min(25, pool.stats.maxSize);\n for (let j = 0; j < warmCount; j++) {\n const buffer = pool.acquire();\n pool.release(buffer);\n }\n }\n }\n\n logger.debug('Object pools pre-warmed with optimal sizes', 'PoolManager', {\n params: paramSize,\n query: querySize,\n headers: headerSize,\n });\n }\n\n /**\n * Get optimal pool size based on buffer size and usage patterns\n */\n private getOptimalPoolSize(bufferSize: number): number {\n // Smaller buffers can have larger pools\n if (bufferSize <= 256) return 100;\n if (bufferSize <= 1024) return 75;\n if (bufferSize <= 4096) return 50;\n return 25; // Large buffers need smaller pools\n }\n\n static getInstance(): ObjectPoolManager {\n if (!this.instance) {\n this.instance = new ObjectPoolManager();\n }\n return this.instance;\n }\n\n /**\n * Reset the singleton (useful for testing)\n */\n static reset(): void {\n if (this.instance) {\n this.instance.clearAll();\n }\n this.instance = null;\n }\n\n // Parameter Object Pool\n\n acquireParams(): Record<string, string> {\n this.performanceStats.totalAcquisitions++;\n const obj = this.paramPool.acquire();\n\n if (this.poolUsageHistory.has('params')) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const history = this.poolUsageHistory.get('params')!;\n if (history.length >= 100) {\n history.shift(); // Keep only last 100 measurements\n }\n history.push(this.paramPool.size);\n } else {\n this.poolUsageHistory.set('params', [this.paramPool.size]);\n }\n\n return obj;\n }\n\n releaseParams(obj: Record<string, string>): void {\n this.performanceStats.totalReleases++;\n this.paramPool.release(obj);\n\n // Adaptive pool sizing based on usage patterns\n if (\n this.adaptiveMode &&\n Date.now() - this.performanceStats.lastAdjustment > this.performanceStats.adjustmentInterval\n ) {\n this.adjustPoolSizes();\n }\n }\n\n // Header Object Pool\n\n acquireHeaders(): Record<string, string> {\n this.performanceStats.totalAcquisitions++;\n return this.headerPool.acquire();\n }\n\n releaseHeaders(obj: Record<string, string>): void {\n this.performanceStats.totalReleases++;\n this.headerPool.release(obj);\n }\n\n // Query Object Pool\n\n acquireQuery(): Record<string, string> {\n this.performanceStats.totalAcquisitions++;\n const obj = this.queryPool.acquire();\n\n const history = this.poolUsageHistory.get('query');\n if (history) {\n if (history.length >= 100) {\n history.shift();\n }\n history.push(this.queryPool.size);\n } else {\n this.poolUsageHistory.set('query', [this.queryPool.size]);\n }\n\n return obj;\n }\n\n releaseQuery(obj: Record<string, string>): void {\n this.performanceStats.totalReleases++;\n this.queryPool.release(obj);\n\n if (\n this.adaptiveMode &&\n Date.now() - this.performanceStats.lastAdjustment > this.performanceStats.adjustmentInterval\n ) {\n this.adjustPoolSizes();\n }\n }\n\n // Request ID Generation\n\n generateRequestId(): string {\n return crypto.randomUUID();\n }\n\n // Buffer Pool\n\n acquireBuffer(size: number): Buffer {\n this.performanceStats.totalAcquisitions++;\n\n // Find smallest buffer that fits\n for (const poolSize of this.bufferSizes) {\n if (size <= poolSize) {\n const pool = this.bufferPools.get(poolSize);\n if (pool) {\n const buffer = pool.acquire();\n this.performanceStats.poolHits++;\n\n // Track usage for adaptive sizing\n const poolKey = `buffer_${poolSize}`;\n if (this.poolUsageHistory.has(poolKey)) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const history = this.poolUsageHistory.get(poolKey)!;\n if (history.length >= 100) {\n history.shift();\n }\n history.push(pool.size);\n } else {\n this.poolUsageHistory.set(poolKey, [pool.size]);\n }\n\n return buffer;\n }\n }\n }\n\n // No pool available for this size, allocate directly\n this.performanceStats.poolMisses++;\n return Buffer.allocUnsafe(size);\n }\n\n releaseBuffer(buffer: Buffer): void {\n this.performanceStats.totalReleases++;\n const size = buffer.length;\n const pool = this.bufferPools.get(size);\n if (pool) {\n pool.release(buffer);\n\n // Adaptive pool sizing based on usage patterns\n if (\n this.adaptiveMode &&\n Date.now() - this.performanceStats.lastAdjustment > this.performanceStats.adjustmentInterval\n ) {\n this.adjustPoolSizes();\n }\n }\n // If no pool for this size, let it be garbage collected\n }\n\n // Route Cache\n\n getCachedRoute(key: string): any {\n return this.routeCache.get(key);\n }\n\n cacheRoute(key: string, route: any): void {\n this.routeCache.set(key, route);\n }\n\n hasCachedRoute(key: string): boolean {\n return this.routeCache.has(key);\n }\n\n clearRouteCache(): void {\n this.routeCache.clear();\n }\n\n // Response Cache (For Opt-In Explicit Caching Only)\n // NOTE: This cache is NOT used automatically by the framework.\n // It's available for developers who explicitly want to cache specific responses.\n // Developers must carefully manage cache keys to avoid stale/incorrect data.\n\n getCachedResponse(\n key: string\n ): { buffer: Buffer; headers: Record<string, string>; statusCode: number } | undefined {\n return this.responseCache.get(key);\n }\n\n cacheResponse(\n key: string,\n buffer: Buffer,\n headers: Record<string, string>,\n statusCode: number = 200\n ): void {\n // Cache responses up to 4KB\n // WARNING: Only use this for static responses that never change\n if (buffer.length < 4096) {\n this.responseCache.set(key, {\n buffer: Buffer.from(buffer), // Clone to avoid mutations\n headers: { ...headers }, // Clone headers\n statusCode,\n });\n }\n }\n\n hasCachedResponse(key: string): boolean {\n return this.responseCache.has(key);\n }\n\n clearResponseCache(): void {\n this.responseCache.clear();\n }\n\n /**\n * Adaptively adjust pool sizes based on usage patterns.\n * Each pool is sized to ~120% of its average observed size, clamped to a\n * [min, max] range, and only resized when the change exceeds a threshold.\n */\n private adjustPoolSizes(): void {\n this.performanceStats.lastAdjustment = Date.now();\n\n const applyFromHistory = (\n pool: ObjectPool<any>,\n historyKey: string,\n min: number,\n max: number,\n threshold: number,\n label: string\n ): void => {\n const history = this.poolUsageHistory.get(historyKey) || [];\n if (history.length < 10) return;\n\n const avgUsage = history.reduce((sum, size) => sum + size, 0) / history.length;\n const targetSize = Math.min(Math.max(Math.round(avgUsage * 1.2), min), max);\n\n if (Math.abs(pool.stats.maxSize - targetSize) > threshold) {\n logger.debug(\n `Adjusting ${label} pool size from ${pool.stats.maxSize} to ${targetSize}`,\n 'PoolManager'\n );\n pool.setMaxSize(targetSize);\n }\n };\n\n applyFromHistory(this.paramPool, 'params', 50, 200, 10, 'param');\n applyFromHistory(this.queryPool, 'query', 50, 200, 10, 'query');\n\n const bufferSizesLen = this.bufferSizes.length;\n for (let i = 0; i < bufferSizesLen; i++) {\n const size = this.bufferSizes[i];\n if (size === undefined) continue;\n const pool = this.bufferPools.get(size);\n if (!pool) continue;\n applyFromHistory(\n pool,\n `buffer_${size}`,\n 10,\n this.getOptimalPoolSize(size) * 2,\n 5,\n `buffer ${size}B`\n );\n }\n\n logger.debug('Pool size adjustment cycle completed', 'PoolManager');\n }\n\n /**\n * Enable or disable adaptive pool sizing\n */\n setAdaptiveMode(enabled: boolean): void {\n this.adaptiveMode = enabled;\n logger.debug(`Adaptive pool sizing ${enabled ? 'enabled' : 'disabled'}`, 'PoolManager');\n }\n\n // Utility Methods\n\n /**\n * Clear all pools and caches\n */\n clearAll(): void {\n this.paramPool.clear();\n this.headerPool.clear();\n this.queryPool.clear();\n this.bufferPools.forEach(pool => pool.clear());\n this.routeCache.clear();\n this.responseCache.clear();\n logger.debug('All pools and caches cleared', 'Maintenance');\n }\n\n /**\n * Force garbage collection on pooled objects\n */\n forceCleanup(): void {\n this.clearAll();\n\n // Force GC if available\n if (globalThis?.gc) {\n globalThis.gc();\n logger.debug('Forced garbage collection', 'Maintenance');\n }\n }\n\n /**\n * Get comprehensive performance statistics\n */\n getStats() {\n const bufferPoolStats: Record<string, any> = {};\n this.bufferPools.forEach((pool, size) => {\n bufferPoolStats[`${size}B`] = pool.stats;\n });\n\n return {\n paramPool: this.paramPool.stats,\n headerPool: this.headerPool.stats,\n queryPool: this.queryPool.stats,\n bufferPools: bufferPoolStats,\n routeCache: this.routeCache.stats,\n responseCache: this.responseCache.stats,\n totalMemory: {\n params: this.paramPool.size * 50, // Rough estimate\n headers: this.headerPool.size * 100, // Rough estimate\n queries: this.queryPool.size * 50, // Rough estimate\n buffers: Array.from(this.bufferPools.values()).reduce((sum, pool) => sum + pool.size, 0),\n routes: this.routeCache.size * 200, // Rough estimate\n responses: this.responseCache.size * 1000, // Rough estimate (increased for full responses)\n },\n };\n }\n\n /**\n * Get performance summary for monitoring\n */\n getPerformanceSummary() {\n const stats = this.getStats();\n const routeCacheTotal = stats.routeCache.hits + stats.routeCache.misses;\n const responseCacheTotal = stats.responseCache.hits + stats.responseCache.misses;\n\n // Manually sum memory instead of Object.values().reduce()\n let totalMemory = 0;\n totalMemory += stats.totalMemory.params;\n totalMemory += stats.totalMemory.headers;\n totalMemory += stats.totalMemory.queries;\n totalMemory += stats.totalMemory.buffers;\n totalMemory += stats.totalMemory.routes;\n totalMemory += stats.totalMemory.responses;\n\n return {\n routeCacheHitRate: routeCacheTotal > 0 ? (stats.routeCache.hits / routeCacheTotal) * 100 : 0,\n responseCacheHitRate:\n responseCacheTotal > 0 ? (stats.responseCache.hits / responseCacheTotal) * 100 : 0,\n paramPoolUtilization: stats.paramPool.utilization * 100,\n totalMemoryKB: totalMemory / 1024,\n };\n }\n\n /**\n * Log performance statistics\n */\n logStats(): void {\n const summary = this.getPerformanceSummary();\n logger.info('ObjectPoolManager Performance', 'Stats', {\n routeCacheHitRate: `${summary.routeCacheHitRate.toFixed(1)}%`,\n responseCacheHitRate: `${summary.responseCacheHitRate.toFixed(1)}%`,\n paramPoolUtilization: `${summary.paramPoolUtilization.toFixed(1)}%`,\n totalMemory: `${summary.totalMemoryKB.toFixed(1)} KB`,\n });\n }\n}\n\n/**\n * Convenience function to get the singleton instance\n */\nexport function getPoolManager(): ObjectPoolManager {\n return ObjectPoolManager.getInstance();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"object-pool-manager.js","sourceRoot":"","sources":["../../../src/core/pooling/object-pool-manager.ts"],"names":[],"mappings":"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","sourcesContent":["// Unified Object Pool Manager\n// Consolidates object pooling from http-server, router, and other components\n\nimport { createFrameworkLogger } from '../logger/index.js';\nimport * as crypto from 'crypto';\nimport { ObjectPool } from './object-pool.js';\nimport { LRUCache } from './lru-cache.js';\nconst logger = createFrameworkLogger('ObjectPoolManager');\n\n/**\n * ObjectPoolManager - Singleton for managing all object pools\n * Consolidates pools from:\n * - MoroHttpServer (paramObjectPool, bufferPool)\n * - Router (paramObjectPool)\n * - Various route caches\n */\nexport class ObjectPoolManager {\n private static instance: ObjectPoolManager | null = null;\n\n // Parameter object pool (for route params)\n private paramPool: ObjectPool<Record<string, string>>;\n\n // Header object pool (for parsed headers)\n private headerPool: ObjectPool<Record<string, string>>;\n\n // Query object pool (for parsed query strings)\n private queryPool: ObjectPool<Record<string, string>>;\n\n // Buffer pools by size\n private bufferPools: Map<number, ObjectPool<Buffer>>;\n private readonly bufferSizes = [64, 256, 1024, 4096, 16384];\n\n // Route lookup cache\n private routeCache: LRUCache<string, any>;\n\n // Response cache (for common responses - now includes full response metadata)\n private responseCache: LRUCache<\n string,\n { buffer: Buffer; headers: Record<string, string>; statusCode: number }\n >;\n\n // Performance monitoring\n private performanceStats = {\n poolHits: 0,\n poolMisses: 0,\n totalAcquisitions: 0,\n totalReleases: 0,\n lastAdjustment: 0,\n adjustmentInterval: 60000, // 1 minute\n };\n\n // Adaptive pool sizing\n private poolUsageHistory: Map<string, number[]> = new Map();\n private adaptiveMode = true;\n\n private constructor() {\n // Set initial last adjustment time to prevent immediate adjustment\n this.performanceStats.lastAdjustment = Date.now();\n\n // Initialize parameter object pool with adaptive sizing\n this.paramPool = new ObjectPool(\n () => ({}),\n 100, // Initial size\n (obj: Record<string, string>) => {\n // Clear all properties\n for (const key in obj) {\n delete obj[key];\n }\n }\n );\n\n // Initialize header object pool\n this.headerPool = new ObjectPool(\n () => ({}),\n 50, // Initial size - headers are less common to pool\n (obj: Record<string, string>) => {\n // Clear all properties\n for (const key in obj) {\n delete obj[key];\n }\n }\n );\n\n // Initialize query object pool\n this.queryPool = new ObjectPool(\n () => ({}),\n 100, // Initial size - queries are very common\n (obj: Record<string, string>) => {\n // Clear all properties\n for (const key in obj) {\n delete obj[key];\n }\n }\n );\n\n // Initialize buffer pools with enhanced sizing\n this.bufferPools = new Map();\n const bufferSizesLen = this.bufferSizes.length;\n for (let i = 0; i < bufferSizesLen; i++) {\n const size = this.bufferSizes[i];\n if (size === undefined) continue;\n this.bufferPools.set(\n size,\n new ObjectPool<Buffer>(() => Buffer.allocUnsafe(size), this.getOptimalPoolSize(size))\n );\n }\n\n // Initialize caches with enhanced statistics\n this.routeCache = new LRUCache(500);\n this.responseCache = new LRUCache(200); // Increased for full response caching\n\n // Pre-warm pools with optimal defaults\n this.preWarmPools();\n\n logger.debug(\n 'ObjectPoolManager initialized with enhanced performance features',\n 'Initialization'\n );\n }\n\n /**\n * Pre-warm pools with optimal sizes for better startup performance\n * Can be called with custom sizes to override defaults\n */\n preWarmPools(sizes?: {\n params?: number;\n query?: number;\n headers?: number;\n buffers?: Record<number, number>;\n }): void {\n // Aggressive pre-warming for common scenarios\n const paramSize = sizes?.params ?? 50; // More aggressive default\n const querySize = sizes?.query ?? 50;\n const headerSize = sizes?.headers ?? 10;\n\n // Acquire the full batch before releasing: an acquire immediately after a\n // release just pops the object that was pushed, so an interleaved loop\n // creates one object no matter the count\n const warm = <T>(pool: { acquire(): T; release(obj: T): void }, count: number): void => {\n const objs: T[] = new Array(count);\n for (let i = 0; i < count; i++) objs[i] = pool.acquire();\n for (let i = 0; i < count; i++) pool.release(objs[i] as T);\n };\n\n warm(this.paramPool, paramSize);\n warm(this.queryPool, querySize);\n warm(this.headerPool, headerSize);\n\n // Pre-warm buffer pools with configurable sizes\n const bufferSizes = sizes?.buffers ?? {};\n const bufferSizesLen = this.bufferSizes.length;\n for (let i = 0; i < bufferSizesLen; i++) {\n const size = this.bufferSizes[i];\n if (size === undefined) continue;\n const pool = this.bufferPools.get(size);\n if (pool) {\n warm(pool, bufferSizes[size] ?? Math.min(25, pool.stats.maxSize));\n }\n }\n\n logger.debug('Object pools pre-warmed with optimal sizes', 'PoolManager', {\n params: paramSize,\n query: querySize,\n headers: headerSize,\n });\n }\n\n /**\n * Get optimal pool size based on buffer size and usage patterns\n */\n private getOptimalPoolSize(bufferSize: number): number {\n // Smaller buffers can have larger pools\n if (bufferSize <= 256) return 100;\n if (bufferSize <= 1024) return 75;\n if (bufferSize <= 4096) return 50;\n return 25; // Large buffers need smaller pools\n }\n\n static getInstance(): ObjectPoolManager {\n if (!this.instance) {\n this.instance = new ObjectPoolManager();\n }\n return this.instance;\n }\n\n /**\n * Reset the singleton (useful for testing)\n */\n static reset(): void {\n if (this.instance) {\n this.instance.clearAll();\n }\n this.instance = null;\n }\n\n // Parameter Object Pool\n\n acquireParams(): Record<string, string> {\n this.performanceStats.totalAcquisitions++;\n const obj = this.paramPool.acquire();\n\n if (this.poolUsageHistory.has('params')) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const history = this.poolUsageHistory.get('params')!;\n if (history.length >= 100) {\n history.shift(); // Keep only last 100 measurements\n }\n history.push(this.paramPool.size);\n } else {\n this.poolUsageHistory.set('params', [this.paramPool.size]);\n }\n\n return obj;\n }\n\n releaseParams(obj: Record<string, string>): void {\n this.performanceStats.totalReleases++;\n this.paramPool.release(obj);\n\n // Adaptive pool sizing based on usage patterns\n if (\n this.adaptiveMode &&\n Date.now() - this.performanceStats.lastAdjustment > this.performanceStats.adjustmentInterval\n ) {\n this.adjustPoolSizes();\n }\n }\n\n // Header Object Pool\n\n acquireHeaders(): Record<string, string> {\n this.performanceStats.totalAcquisitions++;\n return this.headerPool.acquire();\n }\n\n releaseHeaders(obj: Record<string, string>): void {\n this.performanceStats.totalReleases++;\n this.headerPool.release(obj);\n }\n\n // Query Object Pool\n\n acquireQuery(): Record<string, string> {\n this.performanceStats.totalAcquisitions++;\n const obj = this.queryPool.acquire();\n\n const history = this.poolUsageHistory.get('query');\n if (history) {\n if (history.length >= 100) {\n history.shift();\n }\n history.push(this.queryPool.size);\n } else {\n this.poolUsageHistory.set('query', [this.queryPool.size]);\n }\n\n return obj;\n }\n\n releaseQuery(obj: Record<string, string>): void {\n this.performanceStats.totalReleases++;\n this.queryPool.release(obj);\n\n if (\n this.adaptiveMode &&\n Date.now() - this.performanceStats.lastAdjustment > this.performanceStats.adjustmentInterval\n ) {\n this.adjustPoolSizes();\n }\n }\n\n // Request ID Generation\n\n generateRequestId(): string {\n return crypto.randomUUID();\n }\n\n // Buffer Pool\n\n acquireBuffer(size: number): Buffer {\n this.performanceStats.totalAcquisitions++;\n\n // Find smallest buffer that fits\n for (const poolSize of this.bufferSizes) {\n if (size <= poolSize) {\n const pool = this.bufferPools.get(poolSize);\n if (pool) {\n const buffer = pool.acquire();\n this.performanceStats.poolHits++;\n\n // Track usage for adaptive sizing\n const poolKey = `buffer_${poolSize}`;\n if (this.poolUsageHistory.has(poolKey)) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const history = this.poolUsageHistory.get(poolKey)!;\n if (history.length >= 100) {\n history.shift();\n }\n history.push(pool.size);\n } else {\n this.poolUsageHistory.set(poolKey, [pool.size]);\n }\n\n return buffer;\n }\n }\n }\n\n // No pool available for this size, allocate directly\n this.performanceStats.poolMisses++;\n return Buffer.allocUnsafe(size);\n }\n\n releaseBuffer(buffer: Buffer): void {\n this.performanceStats.totalReleases++;\n const size = buffer.length;\n const pool = this.bufferPools.get(size);\n if (pool) {\n pool.release(buffer);\n\n // Adaptive pool sizing based on usage patterns\n if (\n this.adaptiveMode &&\n Date.now() - this.performanceStats.lastAdjustment > this.performanceStats.adjustmentInterval\n ) {\n this.adjustPoolSizes();\n }\n }\n // If no pool for this size, let it be garbage collected\n }\n\n // Route Cache\n\n getCachedRoute(key: string): any {\n return this.routeCache.get(key);\n }\n\n cacheRoute(key: string, route: any): void {\n this.routeCache.set(key, route);\n }\n\n hasCachedRoute(key: string): boolean {\n return this.routeCache.has(key);\n }\n\n clearRouteCache(): void {\n this.routeCache.clear();\n }\n\n // Response Cache (For Opt-In Explicit Caching Only)\n // NOTE: This cache is NOT used automatically by the framework.\n // It's available for developers who explicitly want to cache specific responses.\n // Developers must carefully manage cache keys to avoid stale/incorrect data.\n\n getCachedResponse(\n key: string\n ): { buffer: Buffer; headers: Record<string, string>; statusCode: number } | undefined {\n return this.responseCache.get(key);\n }\n\n cacheResponse(\n key: string,\n buffer: Buffer,\n headers: Record<string, string>,\n statusCode: number = 200\n ): void {\n // Cache responses up to 4KB\n // WARNING: Only use this for static responses that never change\n if (buffer.length < 4096) {\n this.responseCache.set(key, {\n buffer: Buffer.from(buffer), // Clone to avoid mutations\n headers: { ...headers }, // Clone headers\n statusCode,\n });\n }\n }\n\n hasCachedResponse(key: string): boolean {\n return this.responseCache.has(key);\n }\n\n clearResponseCache(): void {\n this.responseCache.clear();\n }\n\n /**\n * Adaptively adjust pool sizes based on usage patterns.\n * Each pool is sized to ~120% of its average observed size, clamped to a\n * [min, max] range, and only resized when the change exceeds a threshold.\n */\n private adjustPoolSizes(): void {\n this.performanceStats.lastAdjustment = Date.now();\n\n const applyFromHistory = (\n pool: ObjectPool<any>,\n historyKey: string,\n min: number,\n max: number,\n threshold: number,\n label: string\n ): void => {\n const history = this.poolUsageHistory.get(historyKey) || [];\n if (history.length < 10) return;\n\n const avgUsage = history.reduce((sum, size) => sum + size, 0) / history.length;\n const targetSize = Math.min(Math.max(Math.round(avgUsage * 1.2), min), max);\n\n if (Math.abs(pool.stats.maxSize - targetSize) > threshold) {\n logger.debug(\n `Adjusting ${label} pool size from ${pool.stats.maxSize} to ${targetSize}`,\n 'PoolManager'\n );\n pool.setMaxSize(targetSize);\n }\n };\n\n applyFromHistory(this.paramPool, 'params', 50, 200, 10, 'param');\n applyFromHistory(this.queryPool, 'query', 50, 200, 10, 'query');\n\n const bufferSizesLen = this.bufferSizes.length;\n for (let i = 0; i < bufferSizesLen; i++) {\n const size = this.bufferSizes[i];\n if (size === undefined) continue;\n const pool = this.bufferPools.get(size);\n if (!pool) continue;\n applyFromHistory(\n pool,\n `buffer_${size}`,\n 10,\n this.getOptimalPoolSize(size) * 2,\n 5,\n `buffer ${size}B`\n );\n }\n\n logger.debug('Pool size adjustment cycle completed', 'PoolManager');\n }\n\n /**\n * Enable or disable adaptive pool sizing\n */\n setAdaptiveMode(enabled: boolean): void {\n this.adaptiveMode = enabled;\n logger.debug(`Adaptive pool sizing ${enabled ? 'enabled' : 'disabled'}`, 'PoolManager');\n }\n\n // Utility Methods\n\n /**\n * Clear all pools and caches\n */\n clearAll(): void {\n this.paramPool.clear();\n this.headerPool.clear();\n this.queryPool.clear();\n this.bufferPools.forEach(pool => pool.clear());\n this.routeCache.clear();\n this.responseCache.clear();\n logger.debug('All pools and caches cleared', 'Maintenance');\n }\n\n /**\n * Force garbage collection on pooled objects\n */\n forceCleanup(): void {\n this.clearAll();\n\n // Force GC if available\n if (globalThis?.gc) {\n globalThis.gc();\n logger.debug('Forced garbage collection', 'Maintenance');\n }\n }\n\n /**\n * Get comprehensive performance statistics\n */\n getStats() {\n const bufferPoolStats: Record<string, any> = {};\n this.bufferPools.forEach((pool, size) => {\n bufferPoolStats[`${size}B`] = pool.stats;\n });\n\n return {\n paramPool: this.paramPool.stats,\n headerPool: this.headerPool.stats,\n queryPool: this.queryPool.stats,\n bufferPools: bufferPoolStats,\n routeCache: this.routeCache.stats,\n responseCache: this.responseCache.stats,\n totalMemory: {\n params: this.paramPool.size * 50, // Rough estimate\n headers: this.headerPool.size * 100, // Rough estimate\n queries: this.queryPool.size * 50, // Rough estimate\n buffers: Array.from(this.bufferPools.values()).reduce((sum, pool) => sum + pool.size, 0),\n routes: this.routeCache.size * 200, // Rough estimate\n responses: this.responseCache.size * 1000, // Rough estimate (increased for full responses)\n },\n };\n }\n\n /**\n * Get performance summary for monitoring\n */\n getPerformanceSummary() {\n const stats = this.getStats();\n const routeCacheTotal = stats.routeCache.hits + stats.routeCache.misses;\n const responseCacheTotal = stats.responseCache.hits + stats.responseCache.misses;\n\n // Manually sum memory instead of Object.values().reduce()\n let totalMemory = 0;\n totalMemory += stats.totalMemory.params;\n totalMemory += stats.totalMemory.headers;\n totalMemory += stats.totalMemory.queries;\n totalMemory += stats.totalMemory.buffers;\n totalMemory += stats.totalMemory.routes;\n totalMemory += stats.totalMemory.responses;\n\n return {\n routeCacheHitRate: routeCacheTotal > 0 ? (stats.routeCache.hits / routeCacheTotal) * 100 : 0,\n responseCacheHitRate:\n responseCacheTotal > 0 ? (stats.responseCache.hits / responseCacheTotal) * 100 : 0,\n paramPoolUtilization: stats.paramPool.utilization * 100,\n totalMemoryKB: totalMemory / 1024,\n };\n }\n\n /**\n * Log performance statistics\n */\n logStats(): void {\n const summary = this.getPerformanceSummary();\n logger.info('ObjectPoolManager Performance', 'Stats', {\n routeCacheHitRate: `${summary.routeCacheHitRate.toFixed(1)}%`,\n responseCacheHitRate: `${summary.responseCacheHitRate.toFixed(1)}%`,\n paramPoolUtilization: `${summary.paramPoolUtilization.toFixed(1)}%`,\n totalMemory: `${summary.totalMemoryKB.toFixed(1)} KB`,\n });\n }\n}\n\n/**\n * Convenience function to get the singleton instance\n */\nexport function getPoolManager(): ObjectPoolManager {\n return ObjectPoolManager.getInstance();\n}\n"]}
|
|
@@ -30,6 +30,8 @@ function segmentEqualsRange(segment, path, start, end) {
|
|
|
30
30
|
}
|
|
31
31
|
export class RadixTree {
|
|
32
32
|
root;
|
|
33
|
+
// Scratch buffer for search() - see the comment there before touching
|
|
34
|
+
paramScratch = [];
|
|
33
35
|
constructor() {
|
|
34
36
|
this.root = {
|
|
35
37
|
segmentHash: 0,
|
|
@@ -159,7 +161,10 @@ export class RadixTree {
|
|
|
159
161
|
* Search for a route in the radix tree - HASH-BASED
|
|
160
162
|
*/
|
|
161
163
|
search(path) {
|
|
162
|
-
|
|
164
|
+
// Reused across calls: search is synchronous and the values are copied
|
|
165
|
+
// into the fresh params object below before returning, so nothing escapes
|
|
166
|
+
const paramValues = this.paramScratch;
|
|
167
|
+
paramValues.length = 0;
|
|
163
168
|
const result = this.searchNode(this.root, path, 0, paramValues);
|
|
164
169
|
if (result) {
|
|
165
170
|
// Build params object using stored parameter names from the matched route
|