krz/hutch
an ios client for sourcehut
clone: git clone https://gitbay.org/krz/hutch.git
v2.13.0: Hutch/Networking/SystemStatusRepository.swift · raw
1import Foundation
2
3actor SystemStatusRepository {
4 private let service: SystemStatusService
5 private let ttl: TimeInterval
6
7 private var snapshotCache: CacheEntry<SystemStatusSnapshot>?
8 private var incidentsCache: CacheEntry<[StatusIncident]>?
9
10 init(service: SystemStatusService = SystemStatusService(), ttl: TimeInterval = 10 * 60) {
11 self.service = service
12 self.ttl = ttl
13 }
14
15 func snapshot(forceRefresh: Bool = false) async throws -> SystemStatusSnapshot {
16 if let cached = snapshotCache, !forceRefresh, !cached.isExpired(ttl: ttl) {
17 return cached.value
18 }
19
20 do {
21 let snapshot = try await service.fetchSnapshot()
22 snapshotCache = CacheEntry(value: snapshot, timestamp: Date())
23 return snapshot
24 } catch {
25 if let cached = snapshotCache {
26 return cached.value
27 }
28 throw error
29 }
30 }
31
32 func recentIncidents(forceRefresh: Bool = false) async throws -> [StatusIncident] {
33 if let cached = incidentsCache, !forceRefresh, !cached.isExpired(ttl: ttl) {
34 return cached.value
35 }
36
37 do {
38 let incidents = try await service.fetchIncidentFeed()
39 incidentsCache = CacheEntry(value: incidents, timestamp: Date())
40 return incidents
41 } catch {
42 if let cached = incidentsCache {
43 return cached.value
44 }
45 throw error
46 }
47 }
48}
49
50private struct CacheEntry<Value: Sendable>: Sendable {
51 let value: Value
52 let timestamp: Date
53
54 nonisolated func isExpired(ttl: TimeInterval) -> Bool {
55 Date().timeIntervalSince(timestamp) > ttl
56 }
57}