fix data race
Since state.Checks() returns a shallow copy its elements must not be modified. Copying the elements in the handler does not guarantee consistency since that list is guarded by a different lock. Therefore, the only solution is to have state.Checks() return a deep copy.
This commit is contained in:
parent
1530f12f56
commit
94fbae4732
|
@ -152,6 +152,7 @@ func (s *HTTPServer) AgentChecks(resp http.ResponseWriter, req *http.Request) (i
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use empty list instead of nil
|
// Use empty list instead of nil
|
||||||
|
// checks needs to be a deep copy for this not be racy
|
||||||
for _, c := range checks {
|
for _, c := range checks {
|
||||||
if c.ServiceTags == nil {
|
if c.ServiceTags == nil {
|
||||||
c.ServiceTags = make([]string, 0)
|
c.ServiceTags = make([]string, 0)
|
||||||
|
|
|
@ -341,12 +341,14 @@ func (l *localState) UpdateCheck(checkID types.CheckID, status, output string) {
|
||||||
// Checks returns the locally registered checks that the
|
// Checks returns the locally registered checks that the
|
||||||
// agent is aware of and are being kept in sync with the server
|
// agent is aware of and are being kept in sync with the server
|
||||||
func (l *localState) Checks() map[types.CheckID]*structs.HealthCheck {
|
func (l *localState) Checks() map[types.CheckID]*structs.HealthCheck {
|
||||||
checks := make(map[types.CheckID]*structs.HealthCheck)
|
|
||||||
l.RLock()
|
l.RLock()
|
||||||
defer l.RUnlock()
|
defer l.RUnlock()
|
||||||
|
|
||||||
for checkID, check := range l.checks {
|
checks := make(map[types.CheckID]*structs.HealthCheck)
|
||||||
checks[checkID] = check
|
for id, c := range l.checks {
|
||||||
|
c2 := new(structs.HealthCheck)
|
||||||
|
*c2 = *c
|
||||||
|
checks[id] = c2
|
||||||
}
|
}
|
||||||
return checks
|
return checks
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue