Exemple #1
0
func getHosts() []string {
	hostsConfigPath := []string{"hailo", "service", "zookeeper", "hosts"}
	tier := config.AtPath("hailo", "service", "zookeeper", "tier").AsString("general")
	if tier != "general" {
		hostsConfigPath = append(hostsConfigPath, tier)
	}

	if hosts := config.AtPath(hostsConfigPath...).AsHostnameArray(2181); len(hosts) > 0 {
		return hosts
	}

	// no hosts returned so try dns
	hosts, err := dns.Hosts("zookeeper-" + tier)
	if err != nil {
		log.Errorf("Failed to load ZK hosts from dns: %v", err)
		return []string{"localhost:2181"}
	}

	// for safety fall back to localhost
	if len(hosts) == 0 {
		return []string{"localhost:2181"}
	}

	// append port
	for i, host := range hosts {
		hosts[i] = host + ":2181"
	}

	return hosts
}
Exemple #2
0
func newdefaultClient() MemcacheClient {
	serverSelector := new(memcache.ServerList)
	client := memcache.NewFromSelector(serverSelector)

	// Listen for config changes
	ch := config.SubscribeChanges()
	go func() {
		for _ = range ch {
			loadFromConfig(serverSelector, client)
		}
	}()

	loadFromConfig(serverSelector, client)

	// Log on init
	hosts := config.AtPath("hailo", "service", "memcache", "servers").AsHostnameArray(11211)
	operationTimeout := config.AtPath("hailo", "service", "memcache", "timeouts", "dialTimeout").
		AsDuration(defaultDialTimeout)
	dialTimeout := config.AtPath("hailo", "service", "memcache", "timeouts", "operationTimeout").
		AsDuration(defaultOperationTimeout)

	log.Infof("[Memcache] Initialising Memcache client to hosts %v: dial timeout %v, op timeout: %v", hosts,
		dialTimeout, operationTimeout)

	return client
}
Exemple #3
0
func getHosts() []string {
	hostConfigPath := []string{"hailo", "service", "memcache", "servers"}
	host := "memcached"

	// check if tier is specified and act accordingly
	tier := config.AtPath("hailo", "service", "memcache", "tier").AsString("")
	if tier != "" {
		hostConfigPath = append(hostConfigPath, tier)
		host = fmt.Sprintf("%s-%s", host, tier)
	}

	if hosts := config.AtPath(hostConfigPath...).AsHostnameArray(11211); len(hosts) > 0 {
		return hosts
	}

	// no hosts returned so try dns
	hosts, err := dns.Hosts(host)
	if err != nil {
		log.Errorf("[Memcache] Failed to load hosts from dns, returning empty list: %v", err)
		return []string{}
	}

	// append port
	for i, host := range hosts {
		hosts[i] = host + ":11211"
	}

	return hosts
}
Exemple #4
0
func getHosts(port int, path ...string) []string {
	if hosts := config.AtPath(path...).AsHostnameArray(port); len(hosts) > 0 {
		return hosts
	}

	// should we lookup dns?
	if config.AtPath("hailo", "service", "nsq", "disableDnsLookup").AsBool() {
		return []string{}
	}

	// try dns lookup
	cluster := config.AtPath("hailo", "service", "nsq", "cluster").AsString("general")
	hosts, err := dns.Hosts("nsq-" + cluster)
	if err != nil {
		log.Errorf("Failed to load NSQ hosts from dns: %v", err)
		return []string{}
	}

	// append port
	for i, host := range hosts {
		hosts[i] = fmt.Sprintf("%s:%d", host, port)
	}

	return hosts
}
Exemple #5
0
func createCircuit(service, endpoint string) Circuit {
	options := defaultOptions
	config.AtPath("hailo", "platform", "circuitbreaker").AsStruct(&options)
	config.AtPath("hailo", "platform", "circuitbreaker", "endpoints", service, endpoint).AsStruct(&options)

	log.Debugf("Circuitbreaker config for %s.%s: %#v", service, endpoint, options)
	return NewDefaultCircuit(options)
}
Exemple #6
0
func loadFromConfig(sl *memcache.ServerList, client *memcache.Client) {
	hosts := getHosts()
	log.Tracef("[Memcache] Setting memcache servers from config: %v", hosts)
	err := sl.SetServers(hosts...)
	if err != nil {
		log.Errorf("[Memcache] Error setting memcache servers: %v", err)
	}

	// Technically we have a race here since the timeouts are not protected by a mutex, however it isn't really a
	// problem if the timeout is stale for a short period.
	client.Timeout = config.AtPath("hailo", "service", "memcache", "timeouts", "operationTimeout").
		AsDuration(defaultOperationTimeout)
	log.Tracef("[Memcache] Set Memcache operation timeout from config: %v", client.Timeout)
	client.DialTimeout = config.AtPath("hailo", "service", "memcache", "timeouts", "dialTimeout").
		AsDuration(defaultDialTimeout)
	log.Tracef("[Memcache] Set Memcache dial timeout from config: %v", client.DialTimeout)
}
Exemple #7
0
func TestPub(t *testing.T) {
	config.LoadFromService("testservice")
	s := config.AtPath("configService", "hash").AsString("default")
	if s == "default" {
		t.Fatal("Failed to load config from config service")
	}
	err := Publish("testtopic", []byte("This is my payload"))
	if err != nil {
		t.Error(fmt.Sprintf("Failed to PUB: %v", err))
	}
}
Exemple #8
0
// run is our main healthcheck loop
func (r *results) run() {
	for {
		select {
		// Listen for config changes and update the healthcheck when needed
		case <-config.SubscribeChanges():
			// Allow healthcheck parameters to be overridden in config
			config.AtPath("hailo", "platform", "healthcheck", r.hc.Id).AsStruct(r.hc)
		case <-runNow:
			r.collect()
		case <-time.After(r.hc.Interval):
			r.collect()
		}
	}
}
Exemple #9
0
// PriorityHealthCheck is a healthcheck with a configurable priority for this server
func PriorityHealthCheck(id string, checker slhc.Checker, priority slhc.Priority) {
	hc := &healthcheck.HealthCheck{
		Id:             id,
		ServiceName:    Name,
		ServiceVersion: Version,
		Hostname:       hostname,
		InstanceId:     InstanceID,
		Interval:       healthcheck.StandardInterval,
		Checker:        checker,
		Priority:       priority,
	}

	// Allow healthcheck parameters to be overridden in config
	config.AtPath("hailo", "platform", "healthcheck", id).AsStruct(hc)

	healthcheck.Register(hc)
}
Exemple #10
0
// shouldTrace determiens if we should trace this request, when sending
func (r *Request) shouldTrace() bool {
	if r.traceID != "" {
		return true
	}

	pcChance := config.AtPath("hailo", "service", "trace", "pcChance").AsFloat64(0)
	if pcChance <= 0 {
		return false
	}

	if rand.Float64() < pcChance {
		u4, err := uuid.NewV4()
		if err != nil {
			return false
		}

		r.SetTraceID(u4.String())
		return true
	}

	return false
}
Exemple #11
0
func reconnectDefault() {
	hosts := getHosts()
	recvTimeout := config.AtPath("hailo", "service", "zookeeper", "recvTimeout").AsDuration("100ms")
	if !hasConfigChanged(hosts, recvTimeout) {
		log.Infof("ZooKeeper config has not changed")
		return
	}

	if defaultClient != nil {
		if recvTimeout != defaultTimeout {
			// cannot gracefully set timeout so close it
			defaultTimeout = recvTimeout
			defaultClient.Close()
		} else {
			// update the hosts only
			log.Tracef("Setting ZK hosts to %v", hosts)
			defaultClient.UpdateAddrs(hosts)
			return
		}
	}

	connectDefault(hosts, recvTimeout)
}
Exemple #12
0
// load will load public key location from config service and switch pub key
func (v *validatorImpl) load() error {
	v.Lock()
	defer v.Unlock()

	fn := config.AtPath("hailo", "service", "authentication", "publicKey").AsString("")
	log.Tracef("[Auth] Loading auth library public key from: %s", fn)
	if fn == "" {
		return fmt.Errorf("public key filename undefined in config")
	}

	// load key from file
	f, err := os.Open(fn)
	if err != nil {
		return fmt.Errorf("Failed to open public key %s (%v)", fn, err)
	}
	b, err := ioutil.ReadAll(f)
	if err != nil {
		return fmt.Errorf("Failed to read public key from %s (%v)", fn, err)
	}

	if bytes.Equal(b, v.lastRead) {
		// no change
		return nil
	}

	// turn bytes into an actual key instance
	k, err := bytesToKey(b)
	if err != nil {
		return fmt.Errorf("Failed to read public key from %s (%v)", fn, err)
	}

	log.Infof("[Auth] Loaded public key: %v", k)

	v.pub = k
	v.lastRead = b
	return nil
}
Exemple #13
0
func (s *DefaultSubscriber) doLoad() error {
	subHosts := config.AtPath("hailo", "service", "nsq", "subHosts").AsHostnameArray(4150)
	disableLookupd := config.AtPath("hailo", "service", "nsq", "disableLookupd").AsBool()
	lookupdHosts := getHosts(4161, "hailo", "service", "nsq", "nsqlookupdSeeds")

	h := md5.New()
	io.WriteString(h, strings.Join(subHosts, ","))
	io.WriteString(h, fmt.Sprintf("%v", disableLookupd))
	io.WriteString(h, strings.Join(lookupdHosts, ","))
	hash := fmt.Sprintf("%x", h.Sum(nil))

	if s.configHash == hash {
		return nil // don't bother as nothing interesting has changed
	}

	if disableLookupd {
		log.Infof("Connecting to NSQ directly: %v", subHosts)
		var hostList []string
		for _, addr := range subHosts {
			// support comma separated host lists too
			hostList = append(hostList, strings.Split(addr, ",")...)
		}
		err := s.consumer.ConnectToNSQDs(hostList)
		if err != nil && err != nsqlib.ErrAlreadyConnected {
			return fmt.Errorf("Error connecting to nsqd(s): %v", err)
		}
	} else {
		if len(lookupdHosts) > 0 {
			log.Infof("Connecting to NSQ via lookupd hosts: %v", lookupdHosts)
			err := s.consumer.ConnectToNSQLookupds(lookupdHosts)
			if err != nil {
				return fmt.Errorf("Error connecting to nsqlookupd(s): %v", err)
			}
		}
	}

	// Disconnect from old hosts
	if hosts := diffHosts(s.subHosts, subHosts); len(hosts) > 0 {
		log.Infof("Disconnecting from NSQ hosts: %v", hosts)
		for _, host := range hosts {
			err := s.consumer.DisconnectFromNSQD(host)
			if err != nil && err != nsqlib.ErrNotConnected {
				log.Warnf("Error disconnecting from NSQ host %s: %v", host, err)
			}
		}
	}

	// Disconnect from old lookupds
	if hosts := diffHosts(s.lookupdHosts, lookupdHosts); len(hosts) > 0 {
		log.Infof("Disconnecting from NSQ lookupds: %v", hosts)
		for _, host := range hosts {
			err := s.consumer.DisconnectFromNSQLookupd(host)
			if err != nil && err != nsqlib.ErrNotConnected {
				log.Warnf("Error disconnecting from NSQ host %s: %v", host, err)
			}
		}
	}

	// save state on success
	s.configHash = hash
	s.subHosts = subHosts
	s.lookupdHosts = lookupdHosts

	return nil
}
Exemple #14
0
func loadPhosphorAddr() string {
	host := config.AtPath("hailo", "service", "trace", "phosphor", "host").AsString("localhost")
	port := config.AtPath("hailo", "service", "trace", "phosphor", "port").AsInt(8130)
	return fmt.Sprintf("%s:%v", host, port)
}
Exemple #15
0
// loadFromConfig grabs latest config, then diffs against currently loaded
func (p *HostpoolPublisher) loadFromConfig() error {
	cl := config.AtPath("hailo", "service", "nsq", "writeCl").AsString("ONE")
	pubHosts := getHosts(4150, "hailo", "service", "nsq", "pubHosts")
	hbInterval := config.AtPath("hailo", "service", "nsq", "pubHeartbeatInterval").AsDuration("30s")

	// hash and test
	hash, _ := config.LastLoaded()
	if p.configHash == hash {
		return nil
	}
	p.configHash = hash

	// lock now and then update everything
	p.Lock()
	defer p.Unlock()

	canonicalHosts := make(map[string]bool)
	for _, host := range pubHosts {
		canonicalHosts[host] = true
		// do we have a producer for this host?
		if _, ok := p.producers[host]; !ok {
			cfg := nsqlib.NewConfig()
			cfg.HeartbeatInterval = hbInterval
			prod, err := nsqlib.NewProducer(host, cfg)
			if err != nil {
				return err
			}
			prod.SetLogger(&logBridge{}, nsqlib.LogLevelDebug)
			p.producers[host] = prod
		}
	}

	// now remove any removed ones
	for host, prod := range p.producers {
		if !canonicalHosts[host] {
			delete(p.producers, host)
			prod.Stop()
		}
	}

	// add hosts to hostpool
	p.hostpool.SetHosts(pubHosts)

	log.Infof("Initialized NSQ publisher with hosts %v", strings.Join(pubHosts, ", "))

	// setup the other meta data
	p.count = len(p.producers)
	switch cl {
	case "TWO":
		p.cl = cl_TWO
		p.n = 2
	case "QUORUM":
		p.cl = cl_QUORUM
		p.n = p.count/2 + 1
	default:
		p.cl = cl_ONE // our default
		p.n = 1
	}

	p.configHash = hash

	return nil
}
Exemple #16
0
func loadStatsdAddr() string {
	host := config.AtPath("hailo", "service", "instrumentation", "statsd", "host").AsString("localhost")
	port := config.AtPath("hailo", "service", "instrumentation", "statsd", "port").AsInt(8125)
	return fmt.Sprintf("%s:%v", host, port)
}
Exemple #17
0
// MaxConnHealthCheck asserts that the total number of established connections to all zookeeper nodes
// falls below a given max threshold.
func MaxConnHealthCheck(maxconns int) healthcheck.Checker {
	return func() (map[string]string, error) {
		nodes := config.AtPath("hailo", "service", "zookeeper", "hosts").AsHostnameArray(2181)
		return connhealthcheck.MaxTcpConnections(nodes, maxconns)()
	}
}