// DiscoverLoop periodically calls orc.discover() until process termination. // The Tablet is read from the given agent each time before calling discover(). // Usually this will be launched as a background goroutine. func (orc *orcClient) DiscoverLoop(agent *ActionAgent) { if *orcInterval == 0 { // 0 means never. return } log.Infof("Starting periodic Orchestrator self-registration: API URL = %v, interval = %v", *orcAddr, *orcInterval) // Randomly vary the interval by +/- 25% to reduce the potential for spikes. ticker := timer.NewRandTicker(*orcInterval, *orcInterval/4) // Remember whether we've most recently succeeded or failed. var lastErr error for { // Do the first attempt immediately. err := orc.Discover(agent.Tablet()) // Only log if we're transitioning between success and failure states. if (err != nil) != (lastErr != nil) { if err != nil { log.Warningf("Orchestrator self-registration attempt failed: %v", err) } else { log.Infof("Orchestrator self-registration succeeded.") } } lastErr = err // Wait for the next tick. // The only way to stop the loop is to terminate the process. <-ticker.C } }
// NewShardConn creates a new ShardConn. It creates a Balancer using // serv, cell, keyspace, tabletType and retryDelay. retryCount is the max // number of retries before a ShardConn returns an error on an operation. func NewShardConn(ctx context.Context, serv topo.SrvTopoServer, cell, keyspace, shard string, tabletType topodatapb.TabletType, retryDelay time.Duration, retryCount int, connTimeoutTotal, connTimeoutPerConn, connLife time.Duration, tabletConnectTimings *stats.MultiTimings) *ShardConn { getAddresses := func() (*topodatapb.EndPoints, error) { endpoints, _, err := serv.GetEndPoints(ctx, cell, keyspace, shard, tabletType) if err != nil { return nil, vterrors.NewVitessError( vtrpcpb.ErrorCode_INTERNAL_ERROR, err, "endpoints fetch error: %v", err, ) } return endpoints, nil } blc := NewBalancer(getAddresses, retryDelay) var ticker *timer.RandTicker if tabletType != topodatapb.TabletType_MASTER { ticker = timer.NewRandTicker(connLife, connLife/2) } sdc := &ShardConn{ keyspace: keyspace, shard: shard, tabletType: tabletType, retryDelay: retryDelay, retryCount: retryCount, connTimeoutTotal: connTimeoutTotal, connTimeoutPerConn: connTimeoutPerConn, connLife: connLife, balancer: blc, ticker: ticker, consolidator: sync2.NewConsolidator(), connectTimings: tabletConnectTimings, } if ticker != nil { go func() { for range ticker.C { sdc.closeCurrent() } }() } return sdc }