Clean up MCPService connections on app quit (#4647)

* Clean up MCPService connections on app quit

* Improve application shutdown error handling
This commit is contained in:
LiuVaayne 2025-04-10 17:19:02 +08:00 committed by GitHub
parent e1f255048e
commit c3b5cbee8f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 1 deletions

View File

@ -3,9 +3,11 @@ import { replaceDevtoolsFont } from '@main/utils/windowUtil'
import { IpcChannel } from '@shared/IpcChannel' import { IpcChannel } from '@shared/IpcChannel'
import { app, ipcMain } from 'electron' import { app, ipcMain } from 'electron'
import installExtension, { REACT_DEVELOPER_TOOLS, REDUX_DEVTOOLS } from 'electron-devtools-installer' import installExtension, { REACT_DEVELOPER_TOOLS, REDUX_DEVTOOLS } from 'electron-devtools-installer'
import Logger from 'electron-log'
import { registerIpc } from './ipc' import { registerIpc } from './ipc'
import { configManager } from './services/ConfigManager' import { configManager } from './services/ConfigManager'
import mcpService from './services/MCPService'
import { CHERRY_STUDIO_PROTOCOL, handleProtocolUrl, registerProtocolClient } from './services/ProtocolClient' import { CHERRY_STUDIO_PROTOCOL, handleProtocolUrl, registerProtocolClient } from './services/ProtocolClient'
import { registerShortcuts } from './services/ShortcutService' import { registerShortcuts } from './services/ShortcutService'
import { TrayService } from './services/TrayService' import { TrayService } from './services/TrayService'
@ -92,6 +94,15 @@ if (!app.requestSingleInstanceLock()) {
app.isQuitting = true app.isQuitting = true
}) })
app.on('will-quit', async () => {
// event.preventDefault()
try {
await mcpService.cleanup()
} catch (error) {
Logger.error('Error cleaning up MCP service:', error)
}
})
// In this file you can include the rest of your app"s specific main process // In this file you can include the rest of your app"s specific main process
// code. You can also put them in separate files and require them here. // code. You can also put them in separate files and require them here.
} }

View File

@ -39,6 +39,7 @@ class McpService {
this.removeServer = this.removeServer.bind(this) this.removeServer = this.removeServer.bind(this)
this.restartServer = this.restartServer.bind(this) this.restartServer = this.restartServer.bind(this)
this.stopServer = this.stopServer.bind(this) this.stopServer = this.stopServer.bind(this)
this.cleanup = this.cleanup.bind(this)
} }
async initClient(server: MCPServer): Promise<Client> { async initClient(server: MCPServer): Promise<Client> {
@ -205,6 +206,16 @@ class McpService {
await this.initClient(server) await this.initClient(server)
} }
async cleanup() {
for (const [key] of this.clients) {
try {
await this.closeClient(key)
} catch (error) {
Logger.error(`[MCP] Failed to close client: ${error}`)
}
}
}
async listTools(_: Electron.IpcMainInvokeEvent, server: MCPServer) { async listTools(_: Electron.IpcMainInvokeEvent, server: MCPServer) {
const client = await this.initClient(server) const client = await this.initClient(server)
const serverKey = this.getServerKey(server) const serverKey = this.getServerKey(server)
@ -324,4 +335,5 @@ class McpService {
} }
} }
export default new McpService() const mcpService = new McpService()
export default mcpService