| 334 | } |
| 335 | |
| 336 | func NewWithStoreClientAndStrategy(cfg Config, name, key string, store kv.Client, strategy ReplicationStrategy, reg prometheus.Registerer, logger log.Logger) (*Ring, error) { |
| 337 | if cfg.ReplicationFactor <= 0 { |
| 338 | return nil, fmt.Errorf("ReplicationFactor must be greater than zero: %d", cfg.ReplicationFactor) |
| 339 | } |
| 340 | |
| 341 | r := &Ring{ |
| 342 | key: key, |
| 343 | cfg: cfg, |
| 344 | KVClient: store, |
| 345 | strategy: strategy, |
| 346 | ringDesc: &Desc{}, |
| 347 | trackedRingZones: map[string]struct{}{}, |
| 348 | shuffledSubringCache: map[subringCacheKey]*Ring{}, |
| 349 | shuffledSubringWithLookbackCache: map[subringCacheKey]cachedSubringWithLookback[*Ring]{}, |
| 350 | numMembersGaugeVec: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{ |
| 351 | Name: "ring_members", |
| 352 | Help: "Number of members in the ring", |
| 353 | ConstLabels: map[string]string{"name": name}, |
| 354 | }, |
| 355 | []string{"state"}), |
| 356 | numZoneMembersGaugeVec: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{ |
| 357 | Name: "ring_zone_members", |
| 358 | Help: "Number of ring members for each zone/state pair", |
| 359 | ConstLabels: map[string]string{"name": name}, |
| 360 | }, []string{"zone", "state"}), |
| 361 | totalTokensGauge: promauto.With(reg).NewGauge(prometheus.GaugeOpts{ |
| 362 | Name: "ring_tokens_total", |
| 363 | Help: "Number of tokens in the ring", |
| 364 | ConstLabels: map[string]string{"name": name}, |
| 365 | }), |
| 366 | oldestTimestampGaugeVec: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{ |
| 367 | Name: "ring_oldest_member_timestamp", |
| 368 | Help: "Timestamp of the oldest member in the ring.", |
| 369 | ConstLabels: map[string]string{"name": name}, |
| 370 | }, |
| 371 | []string{"state"}), |
| 372 | logger: logger, |
| 373 | } |
| 374 | |
| 375 | r.Service = services.NewBasicService(r.starting, r.loop, nil).WithName(fmt.Sprintf("%s ring client", name)) |
| 376 | return r, nil |
| 377 | } |
| 378 | |
| 379 | func (r *Ring) starting(ctx context.Context) error { |
| 380 | // Get the initial ring state so that, as soon as the service will be running, the in-memory |