Commit 8b661d9f36
Unsigned
Layout: unified · split
DomainDig/IntegrationService.swift +52 −6
| @@ -100,9 +100,22 @@ final class IntegrationService { | ||
| 100 | 100 | |
| 101 | 101 | func enqueue(events: [MonitoringEvent]) { |
| 102 | 102 | guard !events.isEmpty else { return } |
| 103 | let eligibleTargets = targets.filter(\.isEnabled) | |
| 104 | 103 | for event in events { |
| 105 | for target in eligibleTargets { | |
| 104 | for target in targets { | |
| 105 | guard target.isEnabled else { | |
| 106 | appendRecord( | |
| 107 | DeliveryRecord( | |
| 108 | integrationID: target.id, | |
| 109 | eventID: event.id, | |
| 110 | status: .skipped, | |
| 111 | destination: destinationLabel(for: target), | |
| 112 | summary: event.summary, | |
| 113 | failureReason: Self.disabledTargetReason | |
| 114 | ) | |
| 115 | ) | |
| 116 | continue | |
| 117 | } | |
| 118 | ||
| 106 | 119 | if let reason = filterMismatchReason(for: event, target: target) { |
| 107 | 120 | appendRecord( |
| 108 | 121 | DeliveryRecord( |
| @@ -150,7 +163,7 @@ final class IntegrationService { | ||
| 150 | 163 | } |
| 151 | 164 | |
| 152 | 165 | func sendTest(for targetID: UUID) { |
| 153 | guard targets.contains(where: { $0.id == targetID }) else { return } | |
| 166 | guard let target = targets.first(where: { $0.id == targetID }) else { return } | |
| 154 | 167 | let event = MonitoringEvent( |
| 155 | 168 | type: .test, |
| 156 | 169 | severity: .info, |
| @@ -161,13 +174,31 @@ final class IntegrationService { | ||
| 161 | 174 | "environment": "local-first" |
| 162 | 175 | ] |
| 163 | 176 | ) |
| 164 | queue.append(QueuedDelivery(integrationID: targetID, event: event)) | |
| 177 | ||
| 178 | // Real events skip a disabled target, so a test event must too — | |
| 179 | // otherwise a test succeeds against a target that silently drops | |
| 180 | // everything monitoring sends it. | |
| 181 | guard target.isEnabled else { | |
| 182 | appendRecord( | |
| 183 | DeliveryRecord( | |
| 184 | integrationID: target.id, | |
| 185 | eventID: event.id, | |
| 186 | status: .skipped, | |
| 187 | destination: destinationLabel(for: target), | |
| 188 | summary: event.summary, | |
| 189 | failureReason: Self.disabledTargetReason | |
| 190 | ) | |
| 191 | ) | |
| 192 | return | |
| 193 | } | |
| 194 | ||
| 195 | queue.append(QueuedDelivery(integrationID: target.id, event: event)) | |
| 165 | 196 | appendRecord( |
| 166 | 197 | DeliveryRecord( |
| 167 | integrationID: targetID, | |
| 198 | integrationID: target.id, | |
| 168 | 199 | eventID: event.id, |
| 169 | 200 | status: .pending, |
| 170 | destination: targets.first(where: { $0.id == targetID }).map(destinationLabel(for:)) ?? "Unknown", | |
| 201 | destination: destinationLabel(for: target), | |
| 171 | 202 | summary: event.summary |
| 172 | 203 | ) |
| 173 | 204 | ) |
| @@ -175,7 +206,20 @@ final class IntegrationService { | ||
| 175 | 206 | scheduleProcessing() |
| 176 | 207 | } |
| 177 | 208 | |
| 209 | /// Restarting the processing task alone leaves any item still in retry | |
| 210 | /// backoff undue, so the loop would skip it and sleep again. Pulling every | |
| 211 | /// queued item forward is what makes this button mean "now". | |
| 178 | 212 | func processQueueNow() { |
| 213 | guard !queue.isEmpty else { | |
| 214 | statusMessage = "No deliveries are waiting." | |
| 215 | return | |
| 216 | } | |
| 217 | ||
| 218 | let now = Date() | |
| 219 | for index in queue.indices { | |
| 220 | queue[index].nextAttemptAt = now | |
| 221 | } | |
| 222 | persistQueue() | |
| 179 | 223 | scheduleProcessing(force: true) |
| 180 | 224 | } |
| 181 | 225 | |
| @@ -427,6 +471,8 @@ final class IntegrationService { | ||
| 427 | 471 | URL(string: string)?.host ?? "Configured" |
| 428 | 472 | } |
| 429 | 473 | |
| 474 | private static let disabledTargetReason = "This integration is disabled." | |
| 475 | ||
| 430 | 476 | private static func secretReference(for integrationID: UUID, suffix: String) -> String { |
| 431 | 477 | "integration.\(integrationID.uuidString).\(suffix)" |
| 432 | 478 | } |