From 10a3e02f4699f50cfff6ba92ff948dac19c8298b Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Mon, 22 Jun 2026 13:27:07 +0800 Subject: [PATCH] fix SDLSuperService --- Tun/Context/SDLContextActor.swift | 4 +- Tun/Super/SDLSuperService.swift | 88 +++++++++++++++++++++---------- 2 files changed, 60 insertions(+), 32 deletions(-) diff --git a/Tun/Context/SDLContextActor.swift b/Tun/Context/SDLContextActor.swift index 8c90a78..34e9f48 100644 --- a/Tun/Context/SDLContextActor.swift +++ b/Tun/Context/SDLContextActor.swift @@ -283,9 +283,7 @@ actor SDLContextActor { } group.addTask { - try await Self.runRestarting(name: "superService") { - try await superService.run() - } + try await superService.run() } group.addTask { diff --git a/Tun/Super/SDLSuperService.swift b/Tun/Super/SDLSuperService.swift index cd1ca5e..19d7dd3 100644 --- a/Tun/Super/SDLSuperService.swift +++ b/Tun/Super/SDLSuperService.swift @@ -9,10 +9,14 @@ actor SDLSuperService { private var onMessage: MessageHandler = { _ in } private var currentSession: SDLSuperSession? private var generation: UInt64 = 0 + private var isRunning = false + private var isStopping = false + private let retryDelay: Duration - init(serverEndpoint: SDLConfiguration.ResolvedServerEndpoint, port: UInt16 = 1443) { + init(serverEndpoint: SDLConfiguration.ResolvedServerEndpoint, port: UInt16 = 1443, retryDelay: Duration = .seconds(5)) { self.serverEndpoint = serverEndpoint self.port = port + self.retryDelay = retryDelay } func updateMessageHandler(_ onMessage: @escaping MessageHandler) { @@ -20,43 +24,60 @@ actor SDLSuperService { } func run() async throws { - let generation = self.nextGeneration() - let session = SDLSuperSession( - serverEndpoint: self.serverEndpoint, - port: self.port, - onMessage: { [weak self] message in - await self?.handleMessage(message, generation: generation) + guard !self.isRunning else { + return + } + + self.isRunning = true + self.isStopping = false + + defer { + self.isRunning = false + self.currentSession = nil + } + + while !Task.isCancelled, !self.isStopping { + let generation = self.nextGeneration() + let session = SDLSuperSession( + serverEndpoint: self.serverEndpoint, + port: self.port, + onMessage: { [weak self] message in + await self?.handleMessage(message, generation: generation) + } + ) + + self.currentSession = session + + do { + try await session.run() + self.clearCurrent(session, generation: generation) + await session.stop() + SDLLogger.log("[SDLSuperService] session ended, will restart", category: .super) + } catch is CancellationError { + self.clearCurrent(session, generation: generation) + await session.stop() + throw CancellationError() + } catch { + self.clearCurrent(session, generation: generation) + await session.stop() + SDLLogger.log("[SDLSuperService] session failed: \(error.localizedDescription), will restart", category: .super) } - ) - self.currentSession = session - - do { - try await session.run() - self.clearCurrent(session, generation: generation) - await session.stop() - } catch is CancellationError { - self.clearCurrent(session, generation: generation) - await session.stop() - throw CancellationError() - } catch { - self.clearCurrent(session, generation: generation) - await session.stop() - throw error + try await Task.sleep(for: self.retryDelay) } } func stop() async { - self.generation &+= 1 - - let session = self.currentSession - self.currentSession = nil - - await session?.stop() + self.isStopping = true + await self.invalidateCurrentSession() } func recoverAfterWake() async { - await self.stop() + guard !self.isStopping else { + return + } + + await self.invalidateCurrentSession() } func send(type: SDLPacketType, data: Data) async { @@ -68,6 +89,15 @@ actor SDLSuperService { return self.generation } + private func invalidateCurrentSession() async { + self.generation &+= 1 + + let session = self.currentSession + self.currentSession = nil + + await session?.stop() + } + private func clearCurrent(_ session: SDLSuperSession, generation: UInt64) { guard self.generation == generation else { return