agent: fix pending data races between localState and agent
This patch creates a local config structure for the local state which is independent from the agent but populated from its configuration. This avoids data races between the agent configuration which can change during tests and concurrent go routines using the configuraiton at the same time.
This commit is contained in:
parent
6715a7a0c2
commit
217d34f66d
|
@ -27,6 +27,21 @@ type syncStatus struct {
|
||||||
inSync bool // Is this in sync with the server
|
inSync bool // Is this in sync with the server
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// localStateConfig is the configuration for the localState. It is
|
||||||
|
// popuplated during NewLocalAgent from the agent configuration to avoid
|
||||||
|
// race conditions with the agent configuration.
|
||||||
|
type localStateConfig struct {
|
||||||
|
ACLToken string
|
||||||
|
AEInterval time.Duration
|
||||||
|
AdvertiseAddr string
|
||||||
|
CheckUpdateInterval time.Duration
|
||||||
|
Datacenter string
|
||||||
|
NodeID types.NodeID
|
||||||
|
NodeName string
|
||||||
|
TaggedAddresses map[string]string
|
||||||
|
TokenForAgent string
|
||||||
|
}
|
||||||
|
|
||||||
// localState is used to represent the node's services,
|
// localState is used to represent the node's services,
|
||||||
// and checks. We used it to perform anti-entropy with the
|
// and checks. We used it to perform anti-entropy with the
|
||||||
// catalog representation
|
// catalog representation
|
||||||
|
@ -39,7 +54,7 @@ type localState struct {
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
|
|
||||||
// Config is the agent config
|
// Config is the agent config
|
||||||
config *Config
|
config localStateConfig
|
||||||
|
|
||||||
// delegate is the consul interface to use for keeping in sync
|
// delegate is the consul interface to use for keeping in sync
|
||||||
delegate delegate
|
delegate delegate
|
||||||
|
@ -76,8 +91,23 @@ type localState struct {
|
||||||
|
|
||||||
// NewLocalState creates a is used to initialize the local state
|
// NewLocalState creates a is used to initialize the local state
|
||||||
func NewLocalState(c *Config, lg *log.Logger) *localState {
|
func NewLocalState(c *Config, lg *log.Logger) *localState {
|
||||||
|
lc := localStateConfig{
|
||||||
|
ACLToken: c.ACLToken,
|
||||||
|
AEInterval: c.AEInterval,
|
||||||
|
AdvertiseAddr: c.AdvertiseAddr,
|
||||||
|
CheckUpdateInterval: c.CheckUpdateInterval,
|
||||||
|
Datacenter: c.Datacenter,
|
||||||
|
NodeID: c.NodeID,
|
||||||
|
NodeName: c.NodeName,
|
||||||
|
TaggedAddresses: map[string]string{},
|
||||||
|
TokenForAgent: c.GetTokenForAgent(),
|
||||||
|
}
|
||||||
|
for k, v := range c.TaggedAddresses {
|
||||||
|
lc.TaggedAddresses[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
return &localState{
|
return &localState{
|
||||||
config: c,
|
config: lc,
|
||||||
logger: lg,
|
logger: lg,
|
||||||
services: make(map[string]*structs.NodeService),
|
services: make(map[string]*structs.NodeService),
|
||||||
serviceStatus: make(map[string]syncStatus),
|
serviceStatus: make(map[string]syncStatus),
|
||||||
|
@ -413,7 +443,7 @@ func (l *localState) setSyncState() error {
|
||||||
req := structs.NodeSpecificRequest{
|
req := structs.NodeSpecificRequest{
|
||||||
Datacenter: l.config.Datacenter,
|
Datacenter: l.config.Datacenter,
|
||||||
Node: l.config.NodeName,
|
Node: l.config.NodeName,
|
||||||
QueryOptions: structs.QueryOptions{Token: l.config.GetTokenForAgent()},
|
QueryOptions: structs.QueryOptions{Token: l.config.TokenForAgent},
|
||||||
}
|
}
|
||||||
var out1 structs.IndexedNodeServices
|
var out1 structs.IndexedNodeServices
|
||||||
var out2 structs.IndexedHealthChecks
|
var out2 structs.IndexedHealthChecks
|
||||||
|
@ -744,7 +774,7 @@ func (l *localState) syncNodeInfo() error {
|
||||||
Address: l.config.AdvertiseAddr,
|
Address: l.config.AdvertiseAddr,
|
||||||
TaggedAddresses: l.config.TaggedAddresses,
|
TaggedAddresses: l.config.TaggedAddresses,
|
||||||
NodeMeta: l.metadata,
|
NodeMeta: l.metadata,
|
||||||
WriteRequest: structs.WriteRequest{Token: l.config.GetTokenForAgent()},
|
WriteRequest: structs.WriteRequest{Token: l.config.TokenForAgent},
|
||||||
}
|
}
|
||||||
var out struct{}
|
var out struct{}
|
||||||
err := l.delegate.RPC("Catalog.Register", &req, &out)
|
err := l.delegate.RPC("Catalog.Register", &req, &out)
|
||||||
|
|
Loading…
Reference in New Issue