63 lines
1.9 KiB
Swift
63 lines
1.9 KiB
Swift
import Foundation
|
|
|
|
public protocol SimAdminClientProtocol: Sendable {
|
|
func send(_ route: UpstreamRoute, baseURL: URL, cookie: String?) async throws -> UpstreamResponse
|
|
}
|
|
|
|
extension SimAdminClient: SimAdminClientProtocol {}
|
|
|
|
public enum ConnectionStatus: String, Equatable, Sendable {
|
|
case online
|
|
case offline
|
|
case authRequired
|
|
case degraded
|
|
case unknown
|
|
|
|
public var label: String {
|
|
switch self {
|
|
case .online: return "在线"
|
|
case .offline: return "离线"
|
|
case .authRequired: return "需登录"
|
|
case .degraded: return "降级"
|
|
case .unknown: return "未知"
|
|
}
|
|
}
|
|
}
|
|
|
|
public struct ConnectionResult: Equatable, Sendable {
|
|
public let status: ConnectionStatus
|
|
public let checkedAt: Date
|
|
|
|
public init(status: ConnectionStatus, checkedAt: Date) {
|
|
self.status = status
|
|
self.checkedAt = checkedAt
|
|
}
|
|
}
|
|
|
|
public struct ConnectionProbe: Sendable {
|
|
private let client: any SimAdminClientProtocol
|
|
|
|
public init(client: any SimAdminClientProtocol) {
|
|
self.client = client
|
|
}
|
|
|
|
public func test(_ instance: Instance) async throws -> ConnectionResult {
|
|
do {
|
|
let response = try await client.send(.health, baseURL: instance.origin, cookie: nil)
|
|
if response.status == 401 || response.status == 403 {
|
|
return ConnectionResult(status: .authRequired, checkedAt: Date())
|
|
}
|
|
return ConnectionResult(status: .online, checkedAt: Date())
|
|
} catch {
|
|
switch error {
|
|
case UpstreamError.unauthorized:
|
|
return ConnectionResult(status: .authRequired, checkedAt: Date())
|
|
case UpstreamError.timeout, is URLError:
|
|
return ConnectionResult(status: .offline, checkedAt: Date())
|
|
default:
|
|
return ConnectionResult(status: .degraded, checkedAt: Date())
|
|
}
|
|
}
|
|
}
|
|
}
|