github.com/uber/kraken@v0.1.4/lib/upstream/config.go (about) 1 // Copyright (c) 2016-2019 Uber Technologies, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package upstream 15 16 import ( 17 "github.com/uber/kraken/lib/hashring" 18 "github.com/uber/kraken/lib/healthcheck" 19 "github.com/uber/kraken/lib/hostlist" 20 "github.com/uber/kraken/utils/log" 21 22 "github.com/andres-erbsen/clock" 23 ) 24 25 // ActiveConfig composes host configuration for an upstream service with an 26 // active health check. 27 type ActiveConfig struct { 28 Hosts hostlist.Config `yaml:"hosts"` 29 HealthCheck ActiveHealthCheckConfig `yaml:"healthcheck"` 30 31 checker healthcheck.Checker 32 } 33 34 // ActiveHealthCheckConfig wraps health check configuration. 35 type ActiveHealthCheckConfig struct { 36 Filter healthcheck.FilterConfig `yaml:"filter"` 37 Monitor healthcheck.MonitorConfig `yaml:"monitor"` 38 Disabled bool `yaml:"disabled"` 39 } 40 41 // ActiveOption allows setting optional ActiveConfig parameters. 42 type ActiveOption func(*ActiveConfig) 43 44 // WithHealthCheck configures ActiveConfig with a custom health check. 45 func WithHealthCheck(checker healthcheck.Checker) ActiveOption { 46 return func(c *ActiveConfig) { c.checker = checker } 47 } 48 49 // Build creates a healthcheck.List with built-in active health checks. 50 func (c ActiveConfig) Build(opts ...ActiveOption) (healthcheck.List, error) { 51 hosts, err := hostlist.New(c.Hosts) 52 if err != nil { 53 return nil, err 54 } 55 if c.HealthCheck.Disabled { 56 log.With("hosts", c.Hosts).Warn("Health checks disabled") 57 return healthcheck.NoopFailed(hosts), nil 58 } 59 c.checker = healthcheck.Default(nil) 60 for _, opt := range opts { 61 opt(&c) 62 } 63 filter := healthcheck.NewFilter(c.HealthCheck.Filter, c.checker) 64 monitor := healthcheck.NewMonitor(c.HealthCheck.Monitor, hosts, filter) 65 return healthcheck.NoopFailed(monitor), nil 66 } 67 68 // StableAddr returns a stable address that can be advertised as the address 69 // for this service. If c is backed by DNS, returns the DNS record. If c is 70 // backed by a static list, returns a random address. 71 func (c ActiveConfig) StableAddr() (string, error) { 72 if c.Hosts.DNS != "" { 73 return c.Hosts.DNS, nil 74 } 75 hosts, err := hostlist.New(c.Hosts) 76 if err != nil { 77 return "", err 78 } 79 addr, err := hosts.Resolve().Random() 80 if err != nil { 81 panic("invariant violation: " + err.Error()) 82 } 83 return addr, nil 84 } 85 86 // PassiveConfig composes host configuruation for an upstream service with a 87 // passive health check. 88 type PassiveConfig struct { 89 Hosts hostlist.Config `yaml:"hosts"` 90 HealthCheck healthcheck.PassiveFilterConfig `yaml:"healthcheck"` 91 } 92 93 // Build creates healthcheck.List enabled with passive health checks. 94 func (c PassiveConfig) Build() (healthcheck.List, error) { 95 hosts, err := hostlist.New(c.Hosts) 96 if err != nil { 97 return nil, err 98 } 99 f := healthcheck.NewPassiveFilter(c.HealthCheck, clock.New()) 100 return healthcheck.NewPassive(hosts, f), nil 101 } 102 103 // PassiveRingConfig composes host configuration for an upstream service with 104 // a passively health checked hash ring. 105 type PassiveHashRingConfig struct { 106 Hosts hostlist.Config `yaml:"hosts"` 107 HealthCheck healthcheck.PassiveFilterConfig `yaml:"healthcheck"` 108 HashRing hashring.Config `yaml:"hashring"` 109 } 110 111 // Build creates a hashring.PassiveRing. 112 func (c PassiveHashRingConfig) Build() (hashring.PassiveRing, error) { 113 hosts, err := hostlist.New(c.Hosts) 114 if err != nil { 115 return nil, err 116 } 117 f := healthcheck.NewPassiveFilter(c.HealthCheck, clock.New()) 118 return hashring.NewPassive(c.HashRing, hosts, f), nil 119 }