syncUpdates updates messages in the store based on the given successful and failed message dispatch results.
(ctx context.Context)
| 236 | |
| 237 | // syncUpdates updates messages in the store based on the given successful and failed message dispatch results. |
| 238 | func (m *Manager) syncUpdates(ctx context.Context) { |
| 239 | // Ensure we update the metrics to reflect the current state after each invocation. |
| 240 | defer func() { |
| 241 | m.metrics.PendingUpdates.Set(float64(len(m.success) + len(m.failure))) |
| 242 | }() |
| 243 | |
| 244 | select { |
| 245 | case <-ctx.Done(): |
| 246 | return |
| 247 | default: |
| 248 | } |
| 249 | |
| 250 | nSuccess := len(m.success) |
| 251 | nFailure := len(m.failure) |
| 252 | |
| 253 | m.metrics.PendingUpdates.Set(float64(nSuccess + nFailure)) |
| 254 | |
| 255 | // Nothing to do. |
| 256 | if nSuccess+nFailure == 0 { |
| 257 | return |
| 258 | } |
| 259 | |
| 260 | var ( |
| 261 | successParams database.BulkMarkNotificationMessagesSentParams |
| 262 | failureParams database.BulkMarkNotificationMessagesFailedParams |
| 263 | ) |
| 264 | |
| 265 | // Read all the existing messages due for update from the channel, but don't range over the channels because they |
| 266 | // block until they are closed. |
| 267 | // |
| 268 | // This is vulnerable to TOCTOU, but it's fine. |
| 269 | // If more items are added to the success or failure channels between measuring their lengths and now, those items |
| 270 | // will be processed on the next bulk update. |
| 271 | |
| 272 | for i := 0; i < nSuccess; i++ { |
| 273 | res := <-m.success |
| 274 | successParams.IDs = append(successParams.IDs, res.msg) |
| 275 | successParams.SentAts = append(successParams.SentAts, res.ts) |
| 276 | } |
| 277 | for i := 0; i < nFailure; i++ { |
| 278 | res := <-m.failure |
| 279 | |
| 280 | var ( |
| 281 | reason string |
| 282 | status database.NotificationMessageStatus |
| 283 | ) |
| 284 | |
| 285 | switch { |
| 286 | case res.retryable: |
| 287 | status = database.NotificationMessageStatusTemporaryFailure |
| 288 | case res.inhibited: |
| 289 | status = database.NotificationMessageStatusInhibited |
| 290 | reason = "disabled by user" |
| 291 | default: |
| 292 | status = database.NotificationMessageStatusPermanentFailure |
| 293 | } |
| 294 | |
| 295 | failureParams.IDs = append(failureParams.IDs, res.msg) |
no test coverage detected