Implement stale entry cleanup in FreebitOperationsService to prevent memory leaks
- Added a method to periodically clean up stale operation timestamps, ensuring efficient memory usage. - Introduced rate limiting for cleanup operations to minimize performance overhead. - Enhanced the getOperationWindow method to invoke cleanup, maintaining optimal state of operation timestamps. - Included validation to ensure at least one feature is specified during updates, improving error handling.
This commit is contained in:
parent
b7f6c204e2
commit
e228f9342f
@ -55,7 +55,51 @@ export class FreebitOperationsService {
|
||||
}
|
||||
>();
|
||||
|
||||
// Rate limit cleanup to avoid running on every operation
|
||||
private lastCleanupTime = 0;
|
||||
private readonly cleanupIntervalMs = 5 * 60 * 1000; // Run cleanup at most every 5 minutes
|
||||
private readonly staleThresholdMs = 35 * 60 * 1000; // Remove entries older than 35 minutes (beyond 30-min window)
|
||||
|
||||
/**
|
||||
* Cleanup stale entries from operationTimestamps to prevent memory leak.
|
||||
* Entries are considered stale when all their timestamps are older than staleThresholdMs.
|
||||
*/
|
||||
private cleanupStaleEntries(): void {
|
||||
const now = Date.now();
|
||||
|
||||
// Rate limit cleanup to avoid performance overhead
|
||||
if (now - this.lastCleanupTime < this.cleanupIntervalMs) {
|
||||
return;
|
||||
}
|
||||
this.lastCleanupTime = now;
|
||||
|
||||
const staleThreshold = now - this.staleThresholdMs;
|
||||
const accountsToRemove: string[] = [];
|
||||
|
||||
for (const [account, entry] of this.operationTimestamps) {
|
||||
const timestamps = [entry.voice, entry.network, entry.plan, entry.cancellation].filter(
|
||||
(t): t is number => typeof t === "number"
|
||||
);
|
||||
|
||||
// If all timestamps are stale (or entry is empty), mark for removal
|
||||
if (timestamps.length === 0 || timestamps.every(t => t < staleThreshold)) {
|
||||
accountsToRemove.push(account);
|
||||
}
|
||||
}
|
||||
|
||||
for (const account of accountsToRemove) {
|
||||
this.operationTimestamps.delete(account);
|
||||
}
|
||||
|
||||
if (accountsToRemove.length > 0) {
|
||||
this.logger.debug(`Cleaned up ${accountsToRemove.length} stale operation timestamp entries`);
|
||||
}
|
||||
}
|
||||
|
||||
private getOperationWindow(account: string) {
|
||||
// Run cleanup periodically to prevent memory leak
|
||||
this.cleanupStaleEntries();
|
||||
|
||||
if (!this.operationTimestamps.has(account)) {
|
||||
this.operationTimestamps.set(account, {});
|
||||
}
|
||||
@ -457,6 +501,14 @@ export class FreebitOperationsService {
|
||||
);
|
||||
}
|
||||
|
||||
// Validate that at least one feature is specified
|
||||
if (!hasVoiceFeatures && !hasNetworkTypeChange) {
|
||||
throw new BadRequestException(
|
||||
"No features specified for update. Please provide at least one of: " +
|
||||
"voiceMailEnabled, callWaitingEnabled, internationalRoamingEnabled, or networkType."
|
||||
);
|
||||
}
|
||||
|
||||
if (hasVoiceFeatures) {
|
||||
// Only voice features (PA05-06)
|
||||
await this.updateVoiceFeatures(account, voiceFeatures);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user