fix: memory leak in session removal - close MCP server properly (#471) (#472)

- Add close() method to N8NDocumentationMCPServer that:
  - Calls server.close() (MCP SDK cleanup)
  - Clears internal cache
  - Nullifies service references to help GC
- Update removeSession() to call server.close() before releasing references

Root cause: removeSession() deleted server from map but didn't call cleanup
Evidence: Production server memory grew ~1GB in 43 minutes (10% to 35%)

Conceived by Romuald Członkowski - https://www.aiadvisors.pl/en

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Romuald Członkowski <romualdczlonkowski@MacBook-Pro-Romuald.local>
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Romuald Członkowski
2025-12-05 18:30:51 +01:00
committed by GitHub
parent 60479e0eb4
commit cdaa29e7a2
12 changed files with 104 additions and 10 deletions

View File

@@ -220,7 +220,46 @@ export class N8NDocumentationMCPServer {
this.setupHandlers();
}
/**
* Close the server and release resources.
* Should be called when the session is being removed.
*
* Order of cleanup:
* 1. Close MCP server connection
* 2. Destroy cache (clears entries AND stops cleanup timer)
* 3. Close database connection
* 4. Null out references to help GC
*/
async close(): Promise<void> {
try {
await this.server.close();
// Use destroy() not clear() - also stops the cleanup timer
this.cache.destroy();
// Close database connection before nullifying reference
if (this.db) {
try {
this.db.close();
} catch (dbError) {
logger.warn('Error closing database', {
error: dbError instanceof Error ? dbError.message : String(dbError)
});
}
}
// Null out references to help garbage collection
this.db = null;
this.repository = null;
this.templateService = null;
this.earlyLogger = null;
} catch (error) {
// Log but don't throw - cleanup should be best-effort
logger.warn('Error closing MCP server', { error: error instanceof Error ? error.message : String(error) });
}
}
private async initializeDatabase(dbPath: string): Promise<void> {
try {
// Checkpoint: Database connecting (v2.18.3)