feat: add alert grace period controls

This commit is contained in:
2026-04-24 19:16:20 +02:00
parent b4163d8c8b
commit d3af580f07
6 changed files with 189 additions and 14 deletions
+21 -2
View File
@@ -50,7 +50,12 @@ enum PingService {
}
private static func handlePingFailure(for hostname: String, notificationsEnabled: Bool) async {
if let notification = await stateStore.recordFailure(for: hostname, notificationsEnabled: notificationsEnabled) {
let alertGracePeriod = UserDefaults.standard.integer(forKey: "alertGracePeriod")
if let notification = await stateStore.recordFailure(
for: hostname,
notificationsEnabled: notificationsEnabled,
gracePeriod: TimeInterval(alertGracePeriod)
) {
sendNotification(title: notification.title, body: notification.body)
}
}
@@ -69,10 +74,12 @@ enum PingService {
private actor PingStateStore {
private var previousPingStates: [String: Bool] = [:]
private var suppressedUntil: [String: Date] = [:]
private var failureStartedAt: [String: Date] = [:]
func suppressChecks(for hostname: String, duration: TimeInterval) {
suppressedUntil[hostname] = Date().addingTimeInterval(duration)
previousPingStates[hostname] = false
failureStartedAt.removeValue(forKey: hostname)
}
func shouldSkipPing(for hostname: String) -> Bool {
@@ -87,6 +94,7 @@ private actor PingStateStore {
func recordSuccess(for hostname: String, notificationsEnabled: Bool) -> PingNotification? {
let wasPreviouslyDown = previousPingStates[hostname] == false
previousPingStates[hostname] = true
failureStartedAt.removeValue(forKey: hostname)
guard wasPreviouslyDown, notificationsEnabled else {
return nil
@@ -98,9 +106,20 @@ private actor PingStateStore {
)
}
func recordFailure(for hostname: String, notificationsEnabled: Bool) -> PingNotification? {
func recordFailure(for hostname: String, notificationsEnabled: Bool, gracePeriod: TimeInterval) -> PingNotification? {
let now = Date()
let startedAt = failureStartedAt[hostname] ?? now
if failureStartedAt[hostname] == nil {
failureStartedAt[hostname] = startedAt
}
guard now.timeIntervalSince(startedAt) >= gracePeriod else {
return nil
}
let wasPreviouslyUp = previousPingStates[hostname] != false
previousPingStates[hostname] = false
failureStartedAt.removeValue(forKey: hostname)
guard wasPreviouslyUp, notificationsEnabled else {
return nil