// hasSomeLifeLeft returns true if the lease has at least a minimum of // lifetime left until expiration, and thus can be used. func (s *LeaseState) hasSomeLifeLeft(clock *hlc.Clock) bool { if s.testingKnobs.CanUseExpiredLeases { return true } minDesiredExpiration := clock.Now().GoTime().Add(MinLeaseDuration) return s.expiration.After(minDesiredExpiration) }
// processReplica processes a single replica. This should not be // called externally to the queue. bq.mu.Lock must not be held // while calling this method. func (bq *baseQueue) processReplica( queueCtx context.Context, repl *Replica, clock *hlc.Clock, ) error { bq.processMu.Lock() defer bq.processMu.Unlock() // Load the system config. cfg, ok := bq.gossip.GetSystemConfig() if !ok { log.VEventf(queueCtx, 1, "no system config available, skipping") return nil } if bq.requiresSplit(cfg, repl) { // Range needs to be split due to zone configs, but queue does // not accept unsplit ranges. log.VEventf(queueCtx, 3, "split needed; skipping") return nil } // Putting a span in a context means that events will no longer go to the // event log. Use queueCtx for events that are intended for the event log. ctx, span := bq.AnnotateCtxWithSpan(queueCtx, bq.name) defer span.Finish() // Also add the Replica annotations to ctx. ctx = repl.AnnotateCtx(ctx) ctx, cancel := context.WithTimeout(ctx, bq.processTimeout) defer cancel() log.Eventf(ctx, "processing replica") if err := repl.IsDestroyed(); err != nil { log.VEventf(queueCtx, 3, "replica destroyed (%s); skipping", err) return nil } // If the queue requires a replica to have the range lease in // order to be processed, check whether this replica has range lease // and renew or acquire if necessary. if bq.needsLease { // Create a "fake" get request in order to invoke redirectOnOrAcquireLease. if err := repl.redirectOnOrAcquireLease(ctx); err != nil { switch v := err.GetDetail().(type) { case *roachpb.NotLeaseHolderError, *roachpb.RangeNotFoundError: log.VEventf(queueCtx, 3, "%s; skipping", v) return nil default: return errors.Wrapf(err.GoError(), "%s: could not obtain lease", repl) } } log.Event(ctx, "got range lease") } log.VEventf(queueCtx, 3, "processing") if err := bq.impl.process(ctx, clock.Now(), repl, cfg); err != nil { return err } log.Event(ctx, "done") bq.successes.Inc(1) return nil }
// waitAndProcess waits for the pace interval and processes the replica // if repl is not nil. The method returns true when the scanner needs // to be stopped. The method also removes a replica from queues when it // is signaled via the removed channel. func (rs *replicaScanner) waitAndProcess( ctx context.Context, start time.Time, clock *hlc.Clock, stopper *stop.Stopper, repl *Replica, ) bool { waitInterval := rs.paceInterval(start, timeutil.Now()) rs.waitTimer.Reset(waitInterval) if log.V(6) { log.Infof(ctx, "wait timer interval set to %s", waitInterval) } for { select { case <-rs.waitTimer.C: if log.V(6) { log.Infof(ctx, "wait timer fired") } rs.waitTimer.Read = true if repl == nil { return false } if log.V(2) { log.Infof(ctx, "replica scanner processing %s", repl) } for _, q := range rs.queues { q.MaybeAdd(repl, clock.Now()) } return false case repl := <-rs.removed: rs.removeReplica(repl) case <-stopper.ShouldStop(): return true } } }
// newTimestampCache returns a new timestamp cache with supplied // hybrid clock. func newTimestampCache(clock *hlc.Clock) *timestampCache { tc := ×tampCache{ rCache: cache.NewIntervalCache(cache.Config{Policy: cache.CacheFIFO}), wCache: cache.NewIntervalCache(cache.Config{Policy: cache.CacheFIFO}), evictionSizeThreshold: defaultEvictionSizeThreshold, } tc.Clear(clock.Now()) tc.rCache.Config.ShouldEvict = tc.shouldEvict tc.wCache.Config.ShouldEvict = tc.shouldEvict return tc }
func (m *LeaseManager) ExpireLeases(clock *hlc.Clock) { past := clock.Now().GoTime().Add(-time.Millisecond) m.tableNames.mu.Lock() for _, lease := range m.tableNames.tables { lease.expiration = parser.DTimestamp{ Time: past, } } m.tableNames.mu.Unlock() }
// MakeRuntimeStatSampler constructs a new RuntimeStatSampler object. func MakeRuntimeStatSampler(clock *hlc.Clock) RuntimeStatSampler { // Construct the build info metric. It is constant. // We first build set the labels on the metadata. info := build.GetInfo() timestamp, err := info.Timestamp() if err != nil { // We can't panic here, tests don't have a build timestamp. log.Warningf(context.TODO(), "Could not parse build timestamp: %v", err) } metaBuildTimestamp.AddLabel("tag", info.Tag) metaBuildTimestamp.AddLabel("go_version", info.GoVersion) buildTimestamp := metric.NewGauge(metaBuildTimestamp) buildTimestamp.Update(timestamp) return RuntimeStatSampler{ clock: clock, startTimeNanos: clock.PhysicalNow(), CgoCalls: metric.NewGauge(metaCgoCalls), Goroutines: metric.NewGauge(metaGoroutines), GoAllocBytes: metric.NewGauge(metaGoAllocBytes), GoTotalBytes: metric.NewGauge(metaGoTotalBytes), CgoAllocBytes: metric.NewGauge(metaCgoAllocBytes), CgoTotalBytes: metric.NewGauge(metaCgoTotalBytes), GcCount: metric.NewGauge(metaGCCount), GcPauseNS: metric.NewGauge(metaGCPauseNS), GcPausePercent: metric.NewGaugeFloat64(metaGCPausePercent), CPUUserNS: metric.NewGauge(metaCPUUserNS), CPUUserPercent: metric.NewGaugeFloat64(metaCPUUserPercent), CPUSysNS: metric.NewGauge(metaCPUSysNS), CPUSysPercent: metric.NewGaugeFloat64(metaCPUSysPercent), Rss: metric.NewGauge(metaRSS), FDOpen: metric.NewGauge(metaFDOpen), FDSoftLimit: metric.NewGauge(metaFDSoftLimit), Uptime: metric.NewGauge(metaUptime), BuildTimestamp: buildTimestamp, } }
// LeaseExpiration returns an int64 to increment a manual clock with to // make sure that all active range leases expire. func (s *Store) LeaseExpiration(clock *hlc.Clock) int64 { // Due to lease extensions, the remaining interval can be longer than just // the sum of the offset (=length of stasis period) and the active // duration, but definitely not by 2x. return 2 * int64(s.cfg.RangeLeaseActiveDuration+clock.MaxOffset()) }
func (l *Liveness) isLive(clock *hlc.Clock) bool { expiration := l.Expiration.Add(-int64(clock.MaxOffset()), 0) return clock.Now().Less(expiration) }
// hasSomeLifeLeft returns true if the lease has at least a minimum of lifetime // left until expiration, and thus can be used. func (s *LeaseState) hasSomeLifeLeft(clock *hlc.Clock) bool { minDesiredExpiration := clock.Now().GoTime().Add(MinLeaseDuration) return s.expiration.After(minDesiredExpiration) }