fix superClient
This commit is contained in:
parent
e7f58dce03
commit
2618ac3d05
@ -61,43 +61,18 @@ final class SDLSuperClient: @unchecked Sendable {
|
|||||||
guard self.markStarted() else {
|
guard self.markStarted() else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let stateStream = self.makeStateStream()
|
||||||
defer {
|
defer {
|
||||||
self.stop()
|
self.stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
let stateStream = Self.makeStateStream(for: self.connection)
|
|
||||||
let promise = AsyncPromise<Bool>()
|
|
||||||
self.connection.start(queue: self.queue)
|
|
||||||
|
|
||||||
try await withTaskCancellationHandler {
|
try await withTaskCancellationHandler {
|
||||||
try await withThrowingTaskGroup { group in
|
self.connection.start(queue: self.queue)
|
||||||
group.addTask {
|
try await self.waitUntilReady(stateStream)
|
||||||
do {
|
try await self.readLoop()
|
||||||
for try await state in stateStream {
|
|
||||||
switch state {
|
|
||||||
case .ready:
|
|
||||||
await promise.succeed(true)
|
|
||||||
default:
|
|
||||||
()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch let err {
|
|
||||||
await promise.fail(err)
|
|
||||||
throw err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
group.addTask {
|
|
||||||
_ = try await promise.value()
|
|
||||||
try Task.checkCancellation()
|
|
||||||
try await self.readLoop()
|
|
||||||
}
|
|
||||||
|
|
||||||
try await group.next()
|
|
||||||
}
|
|
||||||
} onCancel: {
|
} onCancel: {
|
||||||
self.stop()
|
self.connection.cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,24 +88,36 @@ final class SDLSuperClient: @unchecked Sendable {
|
|||||||
preconditionFailure("invalid super server IP: \(ip)")
|
preconditionFailure("invalid super server IP: \(ip)")
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func makeStateStream(for connection: NWConnection) -> AsyncThrowingStream<NWConnection.State, Error> {
|
private func makeStateStream() -> AsyncThrowingStream<NWConnection.State, Error> {
|
||||||
|
let connection = self.connection
|
||||||
return AsyncThrowingStream(bufferingPolicy: .bufferingNewest(16)) { continuation in
|
return AsyncThrowingStream(bufferingPolicy: .bufferingNewest(16)) { continuation in
|
||||||
connection.stateUpdateHandler = { state in
|
connection.stateUpdateHandler = { [weak self] state in
|
||||||
SDLLogger.log("[SDLSuperClient] new state: \(state)", for: .debug)
|
SDLLogger.log("[SDLSuperClient] new state: \(state)", for: .debug)
|
||||||
switch state {
|
switch state {
|
||||||
case .failed(let error):
|
case .failed(let error):
|
||||||
continuation.finish(throwing: error)
|
let wrappedError = SDLSuperError.connectionFailed(error)
|
||||||
|
self?.finishMessageStream(throwing: wrappedError)
|
||||||
|
continuation.finish(throwing: wrappedError)
|
||||||
case .cancelled:
|
case .cancelled:
|
||||||
|
self?.finishMessageStream(throwing: SDLSuperError.connectionCancelled)
|
||||||
continuation.finish(throwing: SDLSuperError.connectionCancelled)
|
continuation.finish(throwing: SDLSuperError.connectionCancelled)
|
||||||
default:
|
default:
|
||||||
continuation.yield(state)
|
continuation.yield(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
continuation.onTermination = { _ in
|
}
|
||||||
connection.stateUpdateHandler = nil
|
|
||||||
|
private func waitUntilReady(_ stateStream: AsyncThrowingStream<NWConnection.State, Error>) async throws {
|
||||||
|
for try await state in stateStream {
|
||||||
|
try Task.checkCancellation()
|
||||||
|
|
||||||
|
if case .ready = state {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw SDLSuperError.connectionCancelled
|
||||||
}
|
}
|
||||||
|
|
||||||
private func readLoop() async throws {
|
private func readLoop() async throws {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user