(ctx context.Context)
| 233 | } |
| 234 | |
| 235 | func (m *Manager) syncReplicas(ctx context.Context) error { |
| 236 | m.closeMutex.Lock() |
| 237 | select { |
| 238 | case <-m.closed: |
| 239 | m.closeMutex.Unlock() |
| 240 | return xerrors.New("manager is closed") |
| 241 | default: |
| 242 | } |
| 243 | m.closeWait.Add(1) |
| 244 | m.closeMutex.Unlock() |
| 245 | defer m.closeWait.Done() |
| 246 | // Expect replicas to update once every three times the interval... |
| 247 | // If they don't, assume death! |
| 248 | // nolint:gocritic // Reading replicas is a system function |
| 249 | replicas, err := m.db.GetReplicasUpdatedAfter(dbauthz.AsSystemRestricted(ctx), m.updateInterval()) |
| 250 | if err != nil { |
| 251 | return xerrors.Errorf("get replicas: %w", err) |
| 252 | } |
| 253 | |
| 254 | m.mutex.Lock() |
| 255 | m.peers = make([]database.Replica, 0, len(replicas)) |
| 256 | for _, replica := range replicas { |
| 257 | if replica.ID == m.id { |
| 258 | continue |
| 259 | } |
| 260 | // Don't peer with nodes that have an empty relay address. |
| 261 | if replica.RelayAddress == "" { |
| 262 | m.logger.Debug(ctx, "peer doesn't have an address, skipping", |
| 263 | slog.F("replica_hostname", replica.Hostname), |
| 264 | ) |
| 265 | continue |
| 266 | } |
| 267 | m.peers = append(m.peers, replica) |
| 268 | } |
| 269 | m.mutex.Unlock() |
| 270 | |
| 271 | client := http.Client{ |
| 272 | Timeout: m.options.PeerTimeout, |
| 273 | Transport: &http.Transport{ |
| 274 | TLSClientConfig: m.options.TLSConfig, |
| 275 | }, |
| 276 | } |
| 277 | defer client.CloseIdleConnections() |
| 278 | |
| 279 | peers := m.Regional() |
| 280 | errs := make(chan error, len(peers)) |
| 281 | for _, peer := range peers { |
| 282 | go func(peer database.Replica) { |
| 283 | err := PingPeerReplica(ctx, client, peer.RelayAddress) |
| 284 | if err != nil { |
| 285 | errs <- xerrors.Errorf("ping sibling replica %s (%s): %w", peer.Hostname, peer.RelayAddress, err) |
| 286 | m.logger.Warn(ctx, "failed to ping sibling replica, this could happen if the replica has shutdown", |
| 287 | slog.F("replica_hostname", peer.Hostname), |
| 288 | slog.F("replica_relay_address", peer.RelayAddress), |
| 289 | slog.Error(err), |
| 290 | ) |
| 291 | return |
| 292 | } |
no test coverage detected