mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-04 22:41:41 +00:00
* feat(apps): support simultaneous gateways * fix(apps): satisfy multi-gateway checks * chore(apps): refresh multi-gateway baselines * style(android): format gateway fleet code
65 lines
2.2 KiB
Swift
65 lines
2.2 KiB
Swift
import Foundation
|
|
import OSLog
|
|
|
|
private let gatewayCronLogger = Logger(subsystem: "ai.openclaw", category: "gateway.connection")
|
|
|
|
extension GatewayConnection {
|
|
private struct LossyDecodable<Value: Decodable>: Decodable {
|
|
let value: Value?
|
|
|
|
init(from decoder: Decoder) throws {
|
|
do {
|
|
self.value = try Value(from: decoder)
|
|
} catch {
|
|
self.value = nil
|
|
}
|
|
}
|
|
}
|
|
|
|
private struct LossyCronListResponse: Decodable {
|
|
let jobs: [LossyDecodable<CronJob>]
|
|
|
|
enum CodingKeys: String, CodingKey {
|
|
case jobs
|
|
}
|
|
|
|
init(from decoder: Decoder) throws {
|
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
|
self.jobs = try container.decodeIfPresent([LossyDecodable<CronJob>].self, forKey: .jobs) ?? []
|
|
}
|
|
}
|
|
|
|
private struct LossyCronRunsResponse: Decodable {
|
|
let entries: [LossyDecodable<CronRunLogEntry>]
|
|
|
|
enum CodingKeys: String, CodingKey {
|
|
case entries
|
|
}
|
|
|
|
init(from decoder: Decoder) throws {
|
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
|
self.entries = try container.decodeIfPresent([LossyDecodable<CronRunLogEntry>].self, forKey: .entries) ?? []
|
|
}
|
|
}
|
|
|
|
nonisolated static func decodeCronListResponse(_ data: Data) throws -> [CronJob] {
|
|
let decoded = try JSONDecoder().decode(LossyCronListResponse.self, from: data)
|
|
let jobs = decoded.jobs.compactMap(\.value)
|
|
let skipped = decoded.jobs.count - jobs.count
|
|
if skipped > 0 {
|
|
gatewayCronLogger.warning("cron.list skipped \(skipped, privacy: .public) malformed jobs")
|
|
}
|
|
return jobs
|
|
}
|
|
|
|
nonisolated static func decodeCronRunsResponse(_ data: Data) throws -> [CronRunLogEntry] {
|
|
let decoded = try JSONDecoder().decode(LossyCronRunsResponse.self, from: data)
|
|
let entries = decoded.entries.compactMap(\.value)
|
|
let skipped = decoded.entries.count - entries.count
|
|
if skipped > 0 {
|
|
gatewayCronLogger.warning("cron.runs skipped \(skipped, privacy: .public) malformed entries")
|
|
}
|
|
return entries
|
|
}
|
|
}
|