fix: memory improvements

- SQLite: enable WAL mode and PRAGMA performance settings

- ws.ts (public + private): fix clientConfigVersions memory leak

- internal server: add rate limiting and request timeouts

- audit log: fix flush re-queue feedback loop

- memory: add monitoring instrumentation

- security: remove debug log of full request body
This commit is contained in:
Josh Voyles
2026-05-02 07:37:18 -04:00
parent bb5853827b
commit d6abe83fdc
9 changed files with 112 additions and 10 deletions

View File

@@ -406,6 +406,10 @@ const removeClient = async (
const updatedClients = existingClients.filter((client) => client !== ws);
if (updatedClients.length === 0) {
connectedClients.delete(mapKey);
// Clean up config version tracking to prevent unbounded memory
// growth. Without this, every unique clientId that ever connects
// leaves a permanent entry in clientConfigVersions.
clientConfigVersions.delete(clientId);
if (redisManager.isRedisEnabled()) {
try {
@@ -413,6 +417,9 @@ const removeClient = async (
await redisManager.del(
getNodeConnectionsKey(NODE_ID, clientId)
);
// Also clean up the Redis config version key so it doesn't
// accumulate indefinitely in Redis either.
await redisManager.del(getConfigVersionKey(clientId));
} catch (error) {
logger.error(
"Failed to remove client from Redis tracking (cleanup will occur on recovery):",
@@ -1097,6 +1104,12 @@ const disconnectClient = async (clientId: string): Promise<boolean> => {
}
});
// Eagerly clean up tracking maps. The close event handlers will also
// call removeClient, but if the socket is already in CLOSING state
// the close event may never fire, leaving zombie entries.
connectedClients.delete(mapKey);
clientConfigVersions.delete(clientId);
return true;
};