diff options
| author | Christian Cleberg <[email protected]> | 2026-04-11 23:36:35 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-04-11 23:36:35 -0500 |
| commit | 00cc231e9b419d27b412036d93457c2cbabe0b16 (patch) | |
| tree | 6b042b802fcddcd1e03f1ae0f666965620225485 /Hutch/Networking/SystemStatusRepository.swift | |
| parent | 0fde7529ceaebf1cd9baa01826d95d587023d001 (diff) | |
| download | hutch-00cc231e9b419d27b412036d93457c2cbabe0b16.tar.gz hutch-00cc231e9b419d27b412036d93457c2cbabe0b16.tar.bz2 hutch-00cc231e9b419d27b412036d93457c2cbabe0b16.zip | |
Add SourceHut system status screen and home disruption banner
Diffstat (limited to 'Hutch/Networking/SystemStatusRepository.swift')
| -rw-r--r-- | Hutch/Networking/SystemStatusRepository.swift | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/Hutch/Networking/SystemStatusRepository.swift b/Hutch/Networking/SystemStatusRepository.swift new file mode 100644 index 0000000..48c5b16 --- /dev/null +++ b/Hutch/Networking/SystemStatusRepository.swift @@ -0,0 +1,57 @@ +import Foundation + +actor SystemStatusRepository { + private let service: SystemStatusService + private let ttl: TimeInterval + + private var snapshotCache: CacheEntry<SystemStatusSnapshot>? + private var incidentsCache: CacheEntry<[StatusIncident]>? + + init(service: SystemStatusService = SystemStatusService(), ttl: TimeInterval = 10 * 60) { + self.service = service + self.ttl = ttl + } + + func snapshot(forceRefresh: Bool = false) async throws -> SystemStatusSnapshot { + if let cached = snapshotCache, !forceRefresh, !cached.isExpired(ttl: ttl) { + return cached.value + } + + do { + let snapshot = try await service.fetchSnapshot() + snapshotCache = CacheEntry(value: snapshot, timestamp: Date()) + return snapshot + } catch { + if let cached = snapshotCache { + return cached.value + } + throw error + } + } + + func recentIncidents(forceRefresh: Bool = false) async throws -> [StatusIncident] { + if let cached = incidentsCache, !forceRefresh, !cached.isExpired(ttl: ttl) { + return cached.value + } + + do { + let incidents = try await service.fetchIncidentFeed() + incidentsCache = CacheEntry(value: incidents, timestamp: Date()) + return incidents + } catch { + if let cached = incidentsCache { + return cached.value + } + throw error + } + } +} + +private struct CacheEntry<Value: Sendable>: Sendable { + let value: Value + let timestamp: Date + + nonisolated func isExpired(ttl: TimeInterval) -> Bool { + Date().timeIntervalSince(timestamp) > ttl + } +} |
