Skip to main content
Glama

Google Drive MCP Server

by ducla5
process-cleanup.ts4.66 kB
/** * Process Cleanup Utilities * Handles graceful shutdown and resource cleanup */ export interface CleanupHandler { name: string; handler: () => Promise<void> | void; priority: number; // Lower numbers run first } export class ProcessCleanup { private static instance: ProcessCleanup | null = null; private handlers: CleanupHandler[] = []; private isShuttingDown = false; private shutdownTimeout = 10000; // 10 seconds private signalsRegistered = false; private constructor() {} /** * Get singleton instance */ static getInstance(): ProcessCleanup { if (!ProcessCleanup.instance) { ProcessCleanup.instance = new ProcessCleanup(); } return ProcessCleanup.instance; } /** * Register a cleanup handler */ registerHandler(handler: CleanupHandler): void { this.handlers.push(handler); this.handlers.sort((a, b) => a.priority - b.priority); // Register signal handlers on first handler registration if (!this.signalsRegistered) { this.registerSignalHandlers(); this.signalsRegistered = true; } } /** * Unregister a cleanup handler by name */ unregisterHandler(name: string): void { this.handlers = this.handlers.filter(h => h.name !== name); } /** * Set shutdown timeout */ setShutdownTimeout(timeout: number): void { this.shutdownTimeout = timeout; } /** * Perform graceful shutdown */ async shutdown(reason: string = 'unknown'): Promise<void> { if (this.isShuttingDown) { return; } this.isShuttingDown = true; console.error(`Initiating graceful shutdown (reason: ${reason})...`); // Set a timeout to force exit if cleanup takes too long const timeoutHandle = setTimeout(() => { console.error('Shutdown timeout reached, forcing exit'); process.exit(1); }, this.shutdownTimeout); try { // Run all cleanup handlers in priority order for (const handler of this.handlers) { try { console.error(`Running cleanup handler: ${handler.name}`); await handler.handler(); console.error(`✓ Cleanup handler completed: ${handler.name}`); } catch (error) { console.error(`✗ Cleanup handler failed: ${handler.name}`, error); } } clearTimeout(timeoutHandle); console.error('Graceful shutdown completed'); process.exit(0); } catch (error) { clearTimeout(timeoutHandle); console.error('Error during shutdown:', error); process.exit(1); } } /** * Register signal handlers for graceful shutdown */ private registerSignalHandlers(): void { const signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM', 'SIGQUIT']; signals.forEach(signal => { process.on(signal, () => { this.shutdown(signal).catch(error => { console.error('Error during signal-triggered shutdown:', error); process.exit(1); }); }); }); // Handle uncaught exceptions process.on('uncaughtException', (error) => { console.error('Uncaught Exception:', error); this.shutdown('uncaughtException').catch(() => { process.exit(1); }); }); // Handle unhandled promise rejections process.on('unhandledRejection', (reason, promise) => { console.error('Unhandled Rejection at:', promise, 'reason:', reason); this.shutdown('unhandledRejection').catch(() => { process.exit(1); }); }); // Handle process exit process.on('exit', (code) => { if (!this.isShuttingDown) { console.error(`Process exiting with code ${code}`); } }); } /** * Check if shutdown is in progress */ isShutdownInProgress(): boolean { return this.isShuttingDown; } /** * Get registered handlers count */ getHandlerCount(): number { return this.handlers.length; } /** * Get handler names */ getHandlerNames(): string[] { return this.handlers.map(h => h.name); } } /** * Convenience function to register a cleanup handler */ export function registerCleanupHandler( name: string, handler: () => Promise<void> | void, priority: number = 100 ): void { ProcessCleanup.getInstance().registerHandler({ name, handler, priority }); } /** * Convenience function to trigger shutdown */ export function triggerShutdown(reason: string = 'manual'): Promise<void> { return ProcessCleanup.getInstance().shutdown(reason); } /** * Convenience function to check if shutdown is in progress */ export function isShutdownInProgress(): boolean { return ProcessCleanup.getInstance().isShutdownInProgress(); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ducla5/gdriver-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server