@noony-serverless/core
Version:
A Middy base framework compatible with Firebase and GCP Cloud Functions with TypeScript
100 lines • 3.59 kB
JavaScript
"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