DEV Community

Ramu Narasinga
Ramu Narasinga

Posted on • Originally published at thinkthroo.com

shutdownManager.ts in mcp-mermaid codebase.

In this article, we review shutdownManager.ts in mcp-mermaid codebase. We will look at:

  1. What is shutdownManager.ts?

  2. Functions defined.

What is shutdownManager.ts?

I found the following comment in mcp-mermaid/src/utils/shutdownManager.ts


/**
 * Centralized shutdown manager for handling cleanup and graceful shutdown
 */
Enter fullscreen mode Exit fullscreen mode

So, this is basically used to cleanup and gracefully shutdown, but what exactly is getting cleaned up? To understand that we will have to pick some references from the mcp-mermaid codebase.

registerCleanup

Example 1:

In mcp-mermaid/src/server.ts, you will find the below code:

// Register server cleanup with shutdown manager
shutdownManager.registerCleanup(createServerCleanup(server));
Enter fullscreen mode Exit fullscreen mode

Example 2:

In mcp-mermaid/src/services/stdio.ts, you will find the below code:

// Register transport cleanup
shutdownManager.registerCleanup(createTransportCleanup(transport));
Enter fullscreen mode Exit fullscreen mode

But how is actual cleanup happening? If you take a closer look at the below code in mcp-mermaid/src/utils/httpServer.ts:

// Setup signal handlers only once
shutdownManager.setupSignalHandlers();
Enter fullscreen mode Exit fullscreen mode

To understand how calling this once cleans up, you will have to understand the functions defined in ShutdownManager.

Functions defined

registerCleanup

export class ShutdownManager {
  private cleanupHandlers: Array<() => void | Promise<void>> = [];
  private isShuttingDown = false;

  /**
   * Register a cleanup handler
   */
  registerCleanup(handler: () => void | Promise<void>): void {
    this.cleanupHandlers.push(handler);
  }
Enter fullscreen mode Exit fullscreen mode

cleanup

async cleanup(): Promise<void> {
    if (this.isShuttingDown) {
      Logger.warn("Shutdown already in progress, forcing exit...");
      process.exit(1);
    }

    this.isShuttingDown = true;
    Logger.info("🔄 Shutting down gracefully...");

    // Execute all cleanup handlers with timeout
    const cleanupPromises = this.cleanupHandlers.map(async (handler) => {
      try {
        await Promise.race([
          handler(),
          new Promise((_, reject) =>
            setTimeout(() => reject(new Error("Cleanup timeout")), 3000),
          ),
        ]);
      } catch (error) {
        Logger.error("Error during cleanup", error);
      }
    });

    await Promise.all(cleanupPromises);
    Logger.success("Cleanup completed");
    process.exit(0);
  }
Enter fullscreen mode Exit fullscreen mode

setupSignalHandlers

/**
* Setup signal handlers for graceful shutdown
*/
setupSignalHandlers(): void {
  // Remove any existing listeners to avoid duplicates
  process.removeAllListeners("SIGINT");
  process.removeAllListeners("SIGTERM");

  process.once("SIGINT", this.cleanup.bind(this));
  process.once("SIGTERM", this.cleanup.bind(this));
}
Enter fullscreen mode Exit fullscreen mode

setupSignalHandlers is setup once and calls the cleanup function when a process terminates, which in this case is, server I am assuming and the process events that are registered here are SIGINT and SIGTERM.

About me:

Hey, my name is Ramu Narasinga. I study codebase architecture in large open-source projects.

Email: ramu.narasinga@gmail.com

Want to learn from open-source? Solve challenges inspired by open-source projects.

References:

  1. https://github.com/hustcc/mcp-mermaid/blob/main/src/utils/shutdownManager.ts#L13

  2. https://github.com/hustcc/mcp-mermaid/blob/ee4b38216771306d48c2ed31f04ce3f2975cc97a/src/server.ts#L40

  3. https://github.com/hustcc/mcp-mermaid/blob/ee4b38216771306d48c2ed31f04ce3f2975cc97a/src/services/stdio.ts#L10

Top comments (0)