UNPKG

@noony-serverless/core

Version:

A Middy base framework compatible with Firebase and GCP Cloud Functions with TypeScript

100 lines 3.59 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.containerPool = exports.ContainerPool = void 0; const typedi_1 = require("typedi"); /** * Performance optimization: Container Pool for reusing TypeDI containers * This reduces object creation overhead and improves memory efficiency */ class ContainerPool { availableContainers = []; maxPoolSize = 10; createdContainers = 0; constructor(maxPoolSize = 10) { this.maxPoolSize = maxPoolSize; } /** * Get a container from the pool or create a new one */ acquire() { if (this.availableContainers.length > 0) { return this.availableContainers.pop(); } // Create new container if pool is empty and under limit if (this.createdContainers < this.maxPoolSize) { this.createdContainers++; return typedi_1.Container.of(); } // If pool is at capacity, create a temporary container // This should rarely happen in normal usage return typedi_1.Container.of(); } /** * Return a container to the pool for reuse */ release(container) { if (this.availableContainers.length < this.maxPoolSize) { // Reset container state by removing all instances // This prevents memory leaks and cross-request contamination this.resetContainer(container); this.availableContainers.push(container); } // If pool is full, let the container be garbage collected } /** * Reset container state to prevent cross-request contamination * Note: TypeDI containers are isolated by default, so we mainly need * to clear any manually set values */ resetContainer(_container) { try { // For TypeDI containers created with Container.of(), each container // is already isolated. We just need to ensure no memory leaks. // The container will be garbage collected when released from pool // if it contains too much data // TypeDI containers are self-contained and don't need explicit reset // This is a placeholder for future enhancements if needed } catch (error) { // If any issues occur, don't add back to pool console.warn('Failed to reset container, discarding:', error); } } /** * Get pool statistics for monitoring */ getStats() { return { available: this.availableContainers.length, created: this.createdContainers, maxSize: this.maxPoolSize, }; } /** * Warm up the pool by pre-creating containers */ warmUp(count = 5) { const warmUpCount = Math.min(count, this.maxPoolSize); for (let i = 0; i < warmUpCount; i++) { if (this.createdContainers < this.maxPoolSize) { const container = typedi_1.Container.of(); this.createdContainers++; this.availableContainers.push(container); } } } /** * Clear all containers from the pool */ clear() { this.availableContainers = []; this.createdContainers = 0; } } exports.ContainerPool = ContainerPool; // Global container pool instance const containerPool = new ContainerPool(15); // Slightly higher limit for serverless exports.containerPool = containerPool; // Warm up the pool for better cold start performance containerPool.warmUp(3); //# sourceMappingURL=containerPool.js.map