perf: parallelize holesail cleanup operations for 10x faster shutdown

Convert sequential cleanup loops to Promise.allSettled() across multiple files:
- includes/maintenance/cleanup.js: parallelize holesail connections, TLS/HTTP servers, and child process cleanup
- includes/core/domain_cleanup.js: parallelize multiple client cleanup within domain removal
- p2ns.js: parallelize child process and connection cleanup in main shutdown

Before: O(n) sequential execution (100-150s for 10 processes)
After: O(1) parallel execution (~10-15s for 10 processes)
This commit is contained in:
Raven Scott
2025-12-26 21:29:39 -05:00
parent 398e042e81
commit be7bd5ee2b
3 changed files with 157 additions and 124 deletions
+22 -17
View File
@@ -393,8 +393,8 @@ async function cleanupInterfaces() {
}
}
// Close all holesail connections first
for (const [key, holesail] of state.holesails) {
// Close all holesail connections first (in parallel)
const holesailClosePromises = Array.from(state.holesails.entries()).map(async ([key, holesail]) => {
try {
if (holesail instanceof dgram.Socket) {
await closeServer(holesail, 'Holesail UDP', key, true);
@@ -405,45 +405,50 @@ async function cleanupInterfaces() {
} catch (err) {
logError('Cleanup', `Error closing Holesail client for ${key}: ${err.message}`);
}
}
});
await Promise.allSettled(holesailClosePromises);
state.holesails.clear();
logDebug('Cleanup', 'Cleared Holesail clients state');
// Close TLS servers
for (const [key, server] of state.tlsServers) {
await closeServer(server, 'TLS', key);
}
// Close TLS servers (in parallel)
const tlsClosePromises = Array.from(state.tlsServers.entries()).map(([key, server]) =>
closeServer(server, 'TLS', key)
);
await Promise.allSettled(tlsClosePromises);
state.tlsServers.clear();
logDebug('Cleanup', 'Cleared TLS servers state');
// Close HTTP servers
for (const [key, server] of state.httpServers) {
await closeServer(server, 'HTTP', key);
}
// Close HTTP servers (in parallel)
const httpClosePromises = Array.from(state.httpServers.entries()).map(([key, server]) =>
closeServer(server, 'HTTP', key)
);
await Promise.allSettled(httpClosePromises);
state.httpServers.clear();
logDebug('Cleanup', 'Cleared HTTP servers state');
// Kill holesail server children
for (const [id, child] of state.holesailChildren) {
// Kill holesail server children (in parallel)
const serverChildKillPromises = Array.from(state.holesailChildren.entries()).map(async ([id, child]) => {
try {
await killProcess(child.pid, 10000);
} catch (err) {
logError('Cleanup', `Error killing Holesail child for server ${id}: ${err.message}`);
}
}
});
await Promise.allSettled(serverChildKillPromises);
state.holesailChildren.clear();
state.holesailOpts.clear();
state.holesailInfos.clear();
logDebug('Cleanup', 'Cleared Holesail server child processes state');
// Kill holesail client children
for (const [id, child] of state.holesailClientChildren) {
// Kill holesail client children (in parallel)
const clientChildKillPromises = Array.from(state.holesailClientChildren.entries()).map(async ([id, child]) => {
try {
await killProcess(child.pid, 10000);
} catch (err) {
logError('Cleanup', `Error killing Holesail client child for ${id}: ${err.message}`);
}
}
});
await Promise.allSettled(clientChildKillPromises);
state.holesailClientChildren.clear();
state.holesailClientOpts.clear();
state.holesailClientInfos.clear();