Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consul name resolution in-memory cache #3121

Merged
merged 30 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
84001c9
nr_consul_cache squashed commits to resolve dco
a-elsheikh Sep 11, 2023
ecd98f0
Update nameresolution/consul/README.md
a-elsheikh Sep 11, 2023
01ed67b
Merge branch 'master' into nr_consul_cache_dco
a-elsheikh Sep 12, 2023
7c7691d
Merge branch 'master' into nr_consul_cache_dco
a-elsheikh Sep 14, 2023
40cbf17
nr_consul_cache refactored to use single routine for watching all ser…
a-elsheikh Sep 20, 2023
f1c0804
Merge branch 'master' into nr_consul_cache_dco
a-elsheikh Sep 20, 2023
a74ee03
nr_consul_cache disable agent cache query for watcher health service …
a-elsheikh Sep 21, 2023
c02778e
Merge branch 'master' into nr_consul_cache_dco
a-elsheikh Sep 22, 2023
673e068
Merge branch 'master' into nr_consul_cache_dco
a-elsheikh Oct 2, 2023
dcb6371
Update nameresolution/consul/consul.go
a-elsheikh Oct 4, 2023
8274b6d
Update nameresolution/consul/consul.go
a-elsheikh Oct 4, 2023
88bdaca
Update nameresolution/consul/consul.go
a-elsheikh Oct 4, 2023
b74f295
Update nameresolution/consul/watcher.go
a-elsheikh Oct 4, 2023
732bc58
Update nameresolution/consul/watcher.go
a-elsheikh Oct 4, 2023
97b537a
Update nameresolution/consul/watcher.go
a-elsheikh Oct 4, 2023
5f18b8e
Update nameresolution/consul/watcher.go
a-elsheikh Oct 4, 2023
b8eb7d5
Update nameresolution/consul/watcher.go
a-elsheikh Oct 4, 2023
74b69a9
merge nr_consul_cache_dco
a-elsheikh Oct 4, 2023
3831d25
use backoff libs, refactor ctx params, some tidy up
a-elsheikh Oct 4, 2023
fb854e6
lint fixes
a-elsheikh Oct 4, 2023
bdb2f29
remove panic recovers
a-elsheikh Oct 4, 2023
b1cbd69
Merge branch 'master' into nr_consul_cache_dco
a-elsheikh Oct 4, 2023
5b0d209
more lint fixes
a-elsheikh Oct 5, 2023
368709f
Merge branch 'nr_consul_cache_dco' of https://github.com/man-group/co…
a-elsheikh Oct 5, 2023
402e2b1
resolve data races in tests
a-elsheikh Oct 5, 2023
0659997
Merge branch 'master' into nr_consul_cache_dco
a-elsheikh Oct 10, 2023
2745d07
💄
ItalyPaleAle Oct 10, 2023
bbfb762
added resolver close method for cleanup and deregister
a-elsheikh Oct 12, 2023
ff8cc37
fix lint issues
a-elsheikh Oct 13, 2023
7c10a9b
Merge branch 'master' into nr_consul_cache_dco
a-elsheikh Oct 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion nameresolution/consul/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ As of writing the configuration spec is fixed to v1.3.0 of the consul api
| Tags | `[]string` | Configures any tags to include if/when registering services |
| Meta | `map[string]string` | Configures any additional metadata to include if/when registering services |
| DaprPortMetaKey | `string` | The key used for getting the Dapr sidecar port from consul service metadata during service resolution, it will also be used to set the Dapr sidecar port in metadata during registration. If blank it will default to `DAPR_PORT` |
| SelfRegister | `bool` | Controls if Dapr will register the service to consul. The name resolution interface does not cater for an "on shutdown" pattern so please consider this if using Dapr to register services to consul as it will not deregister services. |
| SelfRegister | `bool` | Controls if Dapr will register the service to consul on startup. If unset it will default to `false` |
| SelfDeregister | `bool` | Controls if Dapr will deregister the service from consul on shutdown. If unset it will default to `false` |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think when we tried to do that (to solve #2490 ) this was a bad idea. It did un-register all instances of an app and not just the one that was going offline.

I would prefer if this wasn't even offered as an option, as it can cause confusion to users.

(And with #2490 merged in 1.12, this isn't needed anyways)

| AdvancedRegistration | [*api.AgentServiceRegistration](https://pkg.go.dev/github.com/hashicorp/consul/api@v1.3.0#AgentServiceRegistration) | Gives full control of service registration through configuration. If configured the component will ignore any configuration of Checks, Tags, Meta and SelfRegister. |
| UseCache | `bool` | Configures if Dapr will cache the resolved services in-memory. This is done using consul [blocking queries](https://www.consul.io/api-docs/features/blocking) which can be configured via the QueryOptions configuration. If unset it will default to `false` |
## Samples Configurations
Expand Down
3 changes: 3 additions & 0 deletions nameresolution/consul/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type intermediateConfig struct {
AdvancedRegistration *AgentServiceRegistration // advanced use-case
DaprPortMetaKey string
SelfRegister bool
SelfDeregister bool
UseCache bool
}

Expand All @@ -49,6 +50,7 @@ type configSpec struct {
AdvancedRegistration *consul.AgentServiceRegistration // advanced use-case
DaprPortMetaKey string
SelfRegister bool
SelfDeregister bool
UseCache bool
}

Expand Down Expand Up @@ -90,6 +92,7 @@ func mapConfig(config intermediateConfig) configSpec {
QueryOptions: mapQueryOptions(config.QueryOptions),
AdvancedRegistration: mapAdvancedRegistration(config.AdvancedRegistration),
SelfRegister: config.SelfRegister,
SelfDeregister: config.SelfDeregister,
DaprPortMetaKey: config.DaprPortMetaKey,
UseCache: config.UseCache,
}
Expand Down
63 changes: 42 additions & 21 deletions nameresolution/consul/consul.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"net"
"strconv"
"sync"
"sync/atomic"

consul "github.com/hashicorp/consul/api"

Expand Down Expand Up @@ -58,6 +59,7 @@ type clientInterface interface {
type agentInterface interface {
Self() (map[string]map[string]interface{}, error)
ServiceRegister(service *consul.AgentServiceRegistration) error
ServiceDeregister(serviceID string) error
}

type healthInterface interface {
Expand All @@ -66,12 +68,12 @@ type healthInterface interface {
}

type resolver struct {
config resolverConfig
logger logger.Logger
client clientInterface
registry registryInterface
watcherStarted bool
watcherMutex sync.Mutex
config resolverConfig
logger logger.Logger
client clientInterface
registry registryInterface
watcherStarted atomic.Bool
watcherStopChannel chan struct{}
}

type registryInterface interface {
Expand All @@ -86,7 +88,7 @@ type registryInterface interface {
}

type registry struct {
entries *sync.Map
entries sync.Map
serviceChannel chan string
}

Expand Down Expand Up @@ -130,9 +132,7 @@ func (r *resolver) getService(service string) (*consul.ServiceEntry, error) {
var services []*consul.ServiceEntry

if r.config.UseCache {
if !r.watcherStarted {
r.startWatcher()
}
r.startWatcher()

entry := r.registry.get(service)
if entry != nil {
Expand Down Expand Up @@ -214,24 +214,26 @@ func (r *registry) registrationChannel() chan string {
}

type resolverConfig struct {
Client *consul.Config
QueryOptions *consul.QueryOptions
Registration *consul.AgentServiceRegistration
DaprPortMetaKey string
UseCache bool
Client *consul.Config
QueryOptions *consul.QueryOptions
Registration *consul.AgentServiceRegistration
DeregisterOnClose bool
DaprPortMetaKey string
UseCache bool
}

// NewResolver creates Consul name resolver.
func NewResolver(logger logger.Logger) nr.Resolver {
return newResolver(logger, resolverConfig{}, &client{}, &registry{entries: &sync.Map{}, serviceChannel: make(chan string, 100)})
return newResolver(logger, resolverConfig{}, &client{}, &registry{serviceChannel: make(chan string, 100)}, make(chan struct{}))
}

func newResolver(logger logger.Logger, resolverConfig resolverConfig, client clientInterface, registry registryInterface) nr.Resolver {
func newResolver(logger logger.Logger, resolverConfig resolverConfig, client clientInterface, registry registryInterface, watcherStopChannel chan struct{}) nr.Resolver {
return &resolver{
logger: logger,
config: resolverConfig,
client: client,
registry: registry,
logger: logger,
config: resolverConfig,
client: client,
registry: registry,
watcherStopChannel: watcherStopChannel,
}
}

Expand Down Expand Up @@ -295,6 +297,24 @@ func (r *resolver) ResolveID(req nr.ResolveRequest) (addr string, err error) {
return formatAddress(addr, port)
}

// Close will stop the watcher and deregister app from consul
func (r *resolver) Close() error {
if r.watcherStarted.Load() {
r.watcherStopChannel <- struct{}{}
}

if r.config.Registration != nil && r.config.DeregisterOnClose {
err := r.client.Agent().ServiceDeregister(r.config.Registration.ID)
if err != nil {
return fmt.Errorf("failed to deregister consul service: %w", err)
}

r.logger.Info("deregistered service from consul")
}

return nil
}

func formatAddress(address string, port string) (addr string, err error) {
if net.ParseIP(address).To4() != nil {
return address + ":" + port, nil
Expand All @@ -317,6 +337,7 @@ func getConfig(metadata nr.Metadata) (resolverCfg resolverConfig, err error) {
}

resolverCfg.DaprPortMetaKey = cfg.DaprPortMetaKey
resolverCfg.DeregisterOnClose = cfg.SelfDeregister
resolverCfg.UseCache = cfg.UseCache

resolverCfg.Client = getClientConfig(cfg)
Expand Down