// 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() }
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) }