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}