Skip to content

Commit 343bb4f

Browse files
committed
fix: port change race condition — only restart on enabled/port change, await listener release
1 parent f8d8337 commit 343bb4f

2 files changed

Lines changed: 25 additions & 14 deletions

File tree

TablePro/Core/MCP/MCPServer.swift

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,23 +92,30 @@ actor MCPServer {
9292
startCleanupTimer()
9393
}
9494

95-
func stop() {
95+
func stop() async {
9696
Self.logger.info("Stopping MCP server")
9797

9898
cleanupTask?.cancel()
9999
cleanupTask = nil
100100

101101
for (_, session) in sessions {
102-
Task {
103-
await session.cancelAllTasks()
104-
await session.cancelSSEConnection()
105-
}
102+
await session.cancelAllTasks()
103+
await session.cancelSSEConnection()
106104
}
107105
sessions.removeAll()
108106

109-
let currentListener = listener
110-
listener = nil
111-
currentListener?.cancel()
107+
if let currentListener = listener {
108+
listener = nil
109+
currentListener.cancel()
110+
// Wait for the listener to fully release the port
111+
await withCheckedContinuation { (continuation: CheckedContinuation<Void, Never>) in
112+
currentListener.stateUpdateHandler = { state in
113+
if case .cancelled = state {
114+
continuation.resume()
115+
}
116+
}
117+
}
118+
}
112119

113120
stateCallback(.stopped)
114121
}

TablePro/Core/Storage/AppSettingsManager.swift

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,16 @@ final class AppSettingsManager {
146146
didSet {
147147
storage.saveMCP(mcp)
148148
SyncChangeTracker.shared.markDirty(.settings, id: "mcp")
149-
let settings = mcp
150-
Task {
151-
if settings.enabled {
152-
await MCPServerManager.shared.restart(port: UInt16(clamping: settings.port))
153-
} else {
154-
await MCPServerManager.shared.stop()
149+
let enabledChanged = mcp.enabled != oldValue.enabled
150+
let portChanged = mcp.port != oldValue.port
151+
if enabledChanged || portChanged {
152+
let settings = mcp
153+
Task {
154+
if settings.enabled {
155+
await MCPServerManager.shared.restart(port: UInt16(clamping: settings.port))
156+
} else {
157+
await MCPServerManager.shared.stop()
158+
}
155159
}
156160
}
157161
}

0 commit comments

Comments
 (0)