Skip to content

Critical: Multiple background processes not properly cleaned up on app exit #29

@BP602

Description

@BP602

Problem Description

Multiple KickTalk Electron processes remain running in the background after app exit, causing system resource waste and potential stability issues.

User Report: "When I looked for running processes in system monitor I had 10 nicktalk node electron processes running in the background."

Impact

  • Resource waste: Multiple zombie processes consuming RAM and CPU
  • Memory leaks: Each background process continues to accumulate memory
  • Network connections: WebSocket connections may remain open
  • System degradation: Performance impact from multiple instances
  • Process limit exhaustion: Could eventually hit system process limits

Root Cause Analysis

Missing Process Exit Handlers

Main Process (src/main/index.js):

  • ❌ No app.on('before-quit') handler for graceful shutdown
  • ❌ No app.on('will-quit') handler for final cleanup
  • ❌ No process signal handlers (SIGINT, SIGTERM) for forced termination
  • ❌ No cleanup of IPC handlers on exit
  • ❌ No tray icon cleanup on exit

Incomplete Renderer Cleanup

ChatProvider (src/renderer/src/providers/ChatProvider.jsx):

  • beforeunload only handles basic cleanup (batching, some intervals)
  • ❌ No cleanup of all active WebSocket connections on exit
  • ❌ No cleanup of all running intervals and timers
  • ❌ Global variables and event listeners not cleaned up

WebSocket Connection Issues

  • KickPusher connections: May not close properly on forced exit
  • 7TV WebSocket connections: May remain open after app termination
  • Connection pooling: Shared connections not properly terminated

Evidence

Current Cleanup Implementation

// Only basic cleanup exists in beforeunload
window.addEventListener("beforeunload", () => {
  useChatStore.getState().cleanupBatching();
  if (presenceUpdatesInterval) clearInterval(presenceUpdatesInterval);
  if (donationBadgesInterval) clearInterval(donationBadgesInterval);
  if (memoryCleanupInterval) clearInterval(memoryCleanupInterval);
});

Missing Critical Cleanup

  1. All WebSocket connections (individual + shared)
  2. All running intervals beyond the 3 currently handled
  3. Event listeners and global state
  4. IPC handlers in main process
  5. Child processes if any are spawned

Reproduction Steps

  1. Start KickTalk application
  2. Connect to multiple chatrooms (increases process complexity)
  3. Close application (via X button, Alt+F4, or force quit)
  4. Check system process monitor
  5. Observe multiple "KickTalk" or "electron" processes still running

Expected Behavior

  • Only one process should remain briefly during cleanup
  • All processes should terminate within 5-10 seconds of app exit
  • No background processes should persist after app closure

Actual Behavior

  • Multiple background processes remain running indefinitely
  • Processes accumulate over multiple app launches/exits
  • Manual process termination required to clean up

Proposed Solution

1. Add Comprehensive Main Process Cleanup

// Add to src/main/index.js
app.on('before-quit', async (event) => {
  event.preventDefault();
  await performCleanup();
  app.quit();
});

const performCleanup = async () => {
  // Cleanup IPC handlers
  // Cleanup tray icon
  // Notify renderer to cleanup
  // Wait for cleanup completion with timeout
};

2. Add Process Signal Handlers

process.on('SIGINT', gracefulShutdown);
process.on('SIGTERM', gracefulShutdown);
process.on('SIGQUIT', gracefulShutdown);

3. Enhance Renderer Cleanup

  • Add cleanup of ALL WebSocket connections
  • Add cleanup of ALL intervals and timers
  • Add cleanup of global state and event listeners
  • Add IPC notification to main process when cleanup complete

4. Add Cleanup Timeout

  • Implement maximum cleanup time (5-10 seconds)
  • Force quit if cleanup hangs
  • Prevent cleanup from blocking app exit indefinitely

Priority

High - This affects system stability and resource usage for all users

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions