blob: 48c5b16ac662faa80502c8693e29a5459c4b67bc (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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
}
}
|