简化 recoverAfterWake
This commit is contained in:
parent
6be5c230fa
commit
dd906db45b
@ -9,51 +9,6 @@ import Foundation
|
|||||||
import NetworkExtension
|
import NetworkExtension
|
||||||
import NIOCore
|
import NIOCore
|
||||||
|
|
||||||
private actor SDLWorkerRestartSignal {
|
|
||||||
private var generation: UInt64 = 0
|
|
||||||
private var waiters: [UUID: CheckedContinuation<UInt64, Never>] = [:]
|
|
||||||
|
|
||||||
func request() {
|
|
||||||
self.generation &+= 1
|
|
||||||
let generation = self.generation
|
|
||||||
let waiters = self.waiters
|
|
||||||
self.waiters.removeAll()
|
|
||||||
|
|
||||||
for waiter in waiters.values {
|
|
||||||
waiter.resume(returning: generation)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func currentGeneration() -> UInt64 {
|
|
||||||
return self.generation
|
|
||||||
}
|
|
||||||
|
|
||||||
func waitForChange(after observedGeneration: UInt64) async -> UInt64 {
|
|
||||||
if self.generation != observedGeneration {
|
|
||||||
return self.generation
|
|
||||||
}
|
|
||||||
|
|
||||||
let id = UUID()
|
|
||||||
return await withTaskCancellationHandler {
|
|
||||||
await withCheckedContinuation { continuation in
|
|
||||||
if self.generation != observedGeneration {
|
|
||||||
continuation.resume(returning: self.generation)
|
|
||||||
} else {
|
|
||||||
self.waiters[id] = continuation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} onCancel: {
|
|
||||||
Task {
|
|
||||||
await self.cancelWaiter(id: id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func cancelWaiter(id: UUID) {
|
|
||||||
self.waiters.removeValue(forKey: id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 上下文环境变量,全局共享
|
// 上下文环境变量,全局共享
|
||||||
/*
|
/*
|
||||||
1. 处理rsa的加解密逻辑
|
1. 处理rsa的加解密逻辑
|
||||||
@ -110,11 +65,6 @@ actor SDLContextActor {
|
|||||||
private var rootTaskID: UUID?
|
private var rootTaskID: UUID?
|
||||||
private var terminalError: Error?
|
private var terminalError: Error?
|
||||||
private let readySignal = AsyncOneShot<Void>()
|
private let readySignal = AsyncOneShot<Void>()
|
||||||
private let superRestartSignal = SDLWorkerRestartSignal()
|
|
||||||
private let udpHoleRestartSignal = SDLWorkerRestartSignal()
|
|
||||||
private let udpHoleV6RestartSignal = SDLWorkerRestartSignal()
|
|
||||||
private let dnsCloudRestartSignal = SDLWorkerRestartSignal()
|
|
||||||
private let dnsLocalRestartSignal = SDLWorkerRestartSignal()
|
|
||||||
|
|
||||||
public init(provider: NEPacketTunnelProvider, config: SDLConfiguration, rsaCipher: RSACipher) {
|
public init(provider: NEPacketTunnelProvider, config: SDLConfiguration, rsaCipher: RSACipher) {
|
||||||
let puncherActor = SDLPuncherActor()
|
let puncherActor = SDLPuncherActor()
|
||||||
@ -265,7 +215,14 @@ actor SDLContextActor {
|
|||||||
await self.packetOutboundActor.updateRuntime(config: self.config, dataCipher: dataCipher)
|
await self.packetOutboundActor.updateRuntime(config: self.config, dataCipher: dataCipher)
|
||||||
await self.packetInboundActor.updateRuntime(config: self.config, dataCipher: dataCipher)
|
await self.packetInboundActor.updateRuntime(config: self.config, dataCipher: dataCipher)
|
||||||
try await self.tunNetworkManager.apply(settings: .init(config: self.config), dnsServer: DNSHelper.dnsServer)
|
try await self.tunNetworkManager.apply(settings: .init(config: self.config), dnsServer: DNSHelper.dnsServer)
|
||||||
await self.restartVolatileResourcesAfterWake()
|
|
||||||
|
SDLLogger.log("[SDLContext] restart volatile resources after wake", category: .context)
|
||||||
|
|
||||||
|
await self.superService.recoverAfterWake()
|
||||||
|
await self.udpHoleService.recoverAfterWake()
|
||||||
|
await self.udpHoleV6Service.recoverAfterWake()
|
||||||
|
await self.dnsCloudService.recoverAfterWake()
|
||||||
|
await self.dnsLocalService.recoverAfterWake()
|
||||||
|
|
||||||
SDLLogger.log("[SDLContext] recoverAfterWake completed, clearedSessions: \(clearedSessions)", category: .context)
|
SDLLogger.log("[SDLContext] recoverAfterWake completed, clearedSessions: \(clearedSessions)", category: .context)
|
||||||
}
|
}
|
||||||
@ -319,11 +276,6 @@ actor SDLContextActor {
|
|||||||
let puncherActor = self.puncherActor
|
let puncherActor = self.puncherActor
|
||||||
let arpResolver = self.arpResolver
|
let arpResolver = self.arpResolver
|
||||||
let readySignal = self.readySignal
|
let readySignal = self.readySignal
|
||||||
let superRestartSignal = self.superRestartSignal
|
|
||||||
let udpHoleRestartSignal = self.udpHoleRestartSignal
|
|
||||||
let udpHoleV6RestartSignal = self.udpHoleV6RestartSignal
|
|
||||||
let dnsCloudRestartSignal = self.dnsCloudRestartSignal
|
|
||||||
let dnsLocalRestartSignal = self.dnsLocalRestartSignal
|
|
||||||
|
|
||||||
try await withThrowingTaskGroup(of: Void.self) { group in
|
try await withThrowingTaskGroup(of: Void.self) { group in
|
||||||
defer {
|
defer {
|
||||||
@ -331,31 +283,31 @@ actor SDLContextActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group.addTask {
|
group.addTask {
|
||||||
try await Self.runRestarting(name: "superService", restartSignal: superRestartSignal) {
|
try await Self.runRestarting(name: "superService") {
|
||||||
try await superService.run()
|
try await superService.run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
group.addTask {
|
group.addTask {
|
||||||
try await Self.runRestarting(name: "udpHoleService", restartSignal: udpHoleRestartSignal) {
|
try await Self.runRestarting(name: "udpHoleService") {
|
||||||
try await udpHoleService.run()
|
try await udpHoleService.run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
group.addTask {
|
group.addTask {
|
||||||
try await Self.runRestarting(name: "udpHoleV6Service", restartSignal: udpHoleV6RestartSignal) {
|
try await Self.runRestarting(name: "udpHoleV6Service") {
|
||||||
try await udpHoleV6Service.run()
|
try await udpHoleV6Service.run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
group.addTask {
|
group.addTask {
|
||||||
try await Self.runRestarting(name: "dnsCloudService", restartSignal: dnsCloudRestartSignal) {
|
try await Self.runRestarting(name: "dnsCloudService") {
|
||||||
try await dnsCloudService.run()
|
try await dnsCloudService.run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
group.addTask {
|
group.addTask {
|
||||||
try await Self.runRestarting(name: "dnsLocalService", restartSignal: dnsLocalRestartSignal) {
|
try await Self.runRestarting(name: "dnsLocalService") {
|
||||||
try await dnsLocalService.run()
|
try await dnsLocalService.run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -439,22 +391,6 @@ actor SDLContextActor {
|
|||||||
await client?.stop()
|
await client?.stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func restartVolatileResourcesAfterWake() async {
|
|
||||||
SDLLogger.log("[SDLContext] restart volatile resources after wake", category: .context)
|
|
||||||
|
|
||||||
await self.superRestartSignal.request()
|
|
||||||
await self.udpHoleRestartSignal.request()
|
|
||||||
await self.udpHoleV6RestartSignal.request()
|
|
||||||
await self.dnsCloudRestartSignal.request()
|
|
||||||
await self.dnsLocalRestartSignal.request()
|
|
||||||
|
|
||||||
await self.superService.recoverAfterWake()
|
|
||||||
await self.udpHoleService.recoverAfterWake()
|
|
||||||
await self.udpHoleV6Service.recoverAfterWake()
|
|
||||||
await self.dnsCloudService.recoverAfterWake()
|
|
||||||
await self.dnsLocalService.recoverAfterWake()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func cleanupRoot() async {
|
private func cleanupRoot() async {
|
||||||
await self.puncherActor.stop()
|
await self.puncherActor.stop()
|
||||||
await self.arpResolver.stop()
|
await self.arpResolver.stop()
|
||||||
@ -687,11 +623,8 @@ extension SDLContextActor {
|
|||||||
private static func runRestarting(
|
private static func runRestarting(
|
||||||
name: String,
|
name: String,
|
||||||
retryDelay: Duration = .seconds(5),
|
retryDelay: Duration = .seconds(5),
|
||||||
restartSignal: SDLWorkerRestartSignal? = nil,
|
|
||||||
operation: @escaping @Sendable () async throws -> Void
|
operation: @escaping @Sendable () async throws -> Void
|
||||||
) async throws {
|
) async throws {
|
||||||
var restartGeneration = await restartSignal?.currentGeneration() ?? 0
|
|
||||||
|
|
||||||
while !Task.isCancelled {
|
while !Task.isCancelled {
|
||||||
do {
|
do {
|
||||||
try Task.checkCancellation()
|
try Task.checkCancellation()
|
||||||
@ -704,45 +637,7 @@ extension SDLContextActor {
|
|||||||
SDLLogger.log("[SDLContext] worker \(name) crashed: \(error.localizedDescription), will restart", category: .context)
|
SDLLogger.log("[SDLContext] worker \(name) crashed: \(error.localizedDescription), will restart", category: .context)
|
||||||
}
|
}
|
||||||
|
|
||||||
let nextGeneration = try await Self.waitForRestartSignalOrDelay(
|
|
||||||
name: name,
|
|
||||||
retryDelay: retryDelay,
|
|
||||||
restartSignal: restartSignal,
|
|
||||||
observedGeneration: restartGeneration
|
|
||||||
)
|
|
||||||
restartGeneration = nextGeneration
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static func waitForRestartSignalOrDelay(
|
|
||||||
name: String,
|
|
||||||
retryDelay: Duration,
|
|
||||||
restartSignal: SDLWorkerRestartSignal?,
|
|
||||||
observedGeneration: UInt64
|
|
||||||
) async throws -> UInt64 {
|
|
||||||
guard let restartSignal else {
|
|
||||||
try await Task.sleep(for: retryDelay)
|
try await Task.sleep(for: retryDelay)
|
||||||
return observedGeneration
|
|
||||||
}
|
|
||||||
|
|
||||||
return try await withThrowingTaskGroup(of: UInt64.self) { group in
|
|
||||||
group.addTask {
|
|
||||||
try await Task.sleep(for: retryDelay)
|
|
||||||
return await restartSignal.currentGeneration()
|
|
||||||
}
|
|
||||||
|
|
||||||
group.addTask {
|
|
||||||
return await restartSignal.waitForChange(after: observedGeneration)
|
|
||||||
}
|
|
||||||
|
|
||||||
let nextGeneration = try await group.next() ?? observedGeneration
|
|
||||||
group.cancelAll()
|
|
||||||
|
|
||||||
if nextGeneration != observedGeneration {
|
|
||||||
SDLLogger.log("[SDLContext] worker \(name) received restart signal", category: .context)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nextGeneration
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user