func getHosts() []string { cassandraHostKey := getCassandraHostConfigKey() config.WaitUntilLoaded(5 * time.Second) port := config.AtPath("hailo", "service", "cassandra", "defaults", "thriftPort").AsInt(defaultPort) if hosts := config.AtPath("hailo", "service", "cassandra", cassandraHostKey).AsHostnameArray(port); len(hosts) > 0 { return hosts } // No hosts returned: try DNS tier := config.AtPath("hailo", "service", "cassandra", "tier").AsString("premium") hosts, err := dns.Hosts("cassandra-" + tier) if err != nil { log.Errorf("Failed to load Cassandra hosts from dns: %v", err) return defaultHosts } if len(hosts) == 0 { return defaultHosts } // We need to append the port to hosts coming from DNS for i, host := range hosts { hosts[i] = host + fmt.Sprintf(":%d", port) } return hosts }
func (s *DefaultSubscriber) configLoop() { // Wait 5 mins for config to load. If we cannot load config by the // then there's most likely a major issue and we should panic. if !config.WaitUntilLoaded(5 * time.Minute) { panic("Waiting 5 mins for config to load") } s.loadFromConfig() ch := config.SubscribeChanges() for { select { case <-ch: s.loadFromConfig() case <-s.stop: return } } }
func getKsConfig(ks string) (ksConfig, error) { if !config.WaitUntilLoaded(5 * time.Second) { return ksConfig{}, fmt.Errorf("Config not loaded") } username, password, err := ksAuth(ks) if err != nil { return ksConfig{}, err } c := ksConfig{ ks: ks, hosts: getHosts(), username: username, password: password, retries: config.AtPath("hailo", "service", "cassandra", "defaults", "maxRetries").AsInt(5), cl: clFromString(config.AtPath("hailo", "service", "cassandra", "defaults", "consistencyLevel").AsString("")), timeout: config.AtPath("hailo", "service", "cassandra", "defaults", "recvTimeout").AsDuration("1s"), } cc := gocql.NewCluster(c.hosts...) cc.ProtoVersion = config.AtPath("hailo", "service", "cassandra", "defaults", "protoVersion").AsInt(2) cc.Consistency = c.cl cc.Compressor = gocql.SnappyCompressor{} cc.DiscoverHosts = false cc.NumConns = config.AtPath("hailo", "service", "cassandra", "defaults", "maxHostConns").AsInt(2) cc.Authenticator = gocql.PasswordAuthenticator{ Username: c.username, Password: c.password, } cc.Timeout = c.timeout cc.Keyspace = c.ks cc.RetryPolicy = &gocql.SimpleRetryPolicy{ NumRetries: c.retries, } cc.PoolConfig.HostSelectionPolicy = gocql.HostPoolHostPolicy( hostpool.NewEpsilonGreedy(c.hosts, 5*time.Minute, &hostpool.LinearEpsilonValueCalculator{}), ) c.cc = cc return c, nil }
// loadFromConfig including contiuous retries until we have managed to load it func (v *validatorImpl) loadFromConfig() { if !config.WaitUntilLoaded(waitForConfigDelay) { // put out a warning anyway, to make it clear we are going to struggle to load key log.Warnf("[Auth] Failed to load config after %v, kicking off public key loading anyway...", waitForConfigDelay) } // block until we load attempts := 0 for { if err := v.load(); err != nil { attempts++ delay := time.Duration(int64(startRetryDelay) * int64(attempts)) if delay > maxRetryDelay { delay = maxRetryDelay } log.Tracef("[Auth] Failed to load public key from config: %v (sleeping for %v)", err, delay) time.Sleep(delay) continue } break } }
// setup is a one-time action that loads PUB hosts from config and sets up a config subscriber func (p *HostpoolPublisher) setup() { // Wait 5 mins for config to load. If we cannot load config by the // then there's most likely a major issue and we should panic. if !config.WaitUntilLoaded(5 * time.Minute) { panic("Waiting 5 mins for config to load") } ch := config.SubscribeChanges() p.loadFromConfig() go func() { for { <-ch for { if err := p.loadFromConfig(); err != nil { log.Warnf("Failed to load NSQ PUB config: %v", err) time.Sleep(configRetryDelay) } else { break } } } }() }