Follows pattern used by ring for WatchKey.
(ctx context.Context)
| 402 | |
| 403 | // Follows pattern used by ring for WatchKey. |
| 404 | func (c *HATracker) loop(ctx context.Context) error { |
| 405 | if !c.cfg.EnableHATracker { |
| 406 | // don't do anything, but wait until asked to stop. |
| 407 | <-ctx.Done() |
| 408 | return nil |
| 409 | } |
| 410 | |
| 411 | // Start cleanup loop. It will stop when context is done. |
| 412 | wg := sync.WaitGroup{} |
| 413 | wg.Add(2) |
| 414 | go func() { |
| 415 | defer wg.Done() |
| 416 | c.cleanupOldReplicasLoop(ctx) |
| 417 | }() |
| 418 | // Start periodic update of user replica group count. |
| 419 | go func() { |
| 420 | defer wg.Done() |
| 421 | ticker := time.NewTicker(userReplicaGroupUpdateInterval) |
| 422 | defer ticker.Stop() |
| 423 | |
| 424 | for { |
| 425 | select { |
| 426 | case <-ticker.C: |
| 427 | c.updateUserReplicaGroupCount() |
| 428 | case <-ctx.Done(): |
| 429 | return |
| 430 | } |
| 431 | } |
| 432 | }() |
| 433 | |
| 434 | // The KVStore config we gave when creating c should have contained a prefix, |
| 435 | // which would have given us a prefixed KVStore client. So, we can pass empty string here. |
| 436 | c.client.WatchPrefix(ctx, "", func(key string, value any) bool { |
| 437 | replica := value.(*ReplicaDesc) |
| 438 | user, cluster, keyHasSeparator := strings.Cut(key, "/") |
| 439 | |
| 440 | // Valid key would look like cluster/replica, and a key without a / such as `ring` would be invalid. |
| 441 | if !keyHasSeparator { |
| 442 | return true |
| 443 | } |
| 444 | |
| 445 | c.electedLock.Lock() |
| 446 | defer c.electedLock.Unlock() |
| 447 | |
| 448 | if replica.DeletedAt > 0 { |
| 449 | delete(c.elected, key) |
| 450 | c.electedReplicaChanges.DeleteLabelValues(user, cluster) |
| 451 | c.electedReplicaTimestamp.DeleteLabelValues(user, cluster) |
| 452 | |
| 453 | userClusters := c.replicaGroups[user] |
| 454 | if userClusters != nil { |
| 455 | delete(userClusters, cluster) |
| 456 | if len(userClusters) == 0 { |
| 457 | delete(c.replicaGroups, user) |
| 458 | } |
| 459 | } |
| 460 | return true |
| 461 | } |
nothing calls this directly
no test coverage detected