etcd: scheduler: Use atomic to prevent race
This code should be rewritten, but in the meantime, at least avoid the race detector issues.
This commit is contained in:
@@ -37,6 +37,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/purpleidea/mgmt/util/errwrap"
|
"github.com/purpleidea/mgmt/util/errwrap"
|
||||||
|
|
||||||
@@ -245,7 +246,7 @@ func Schedule(client *etcd.Client, path string, hostname string, opts ...Option)
|
|||||||
|
|
||||||
mutex := &sync.Mutex{}
|
mutex := &sync.Mutex{}
|
||||||
var campaignClose chan struct{}
|
var campaignClose chan struct{}
|
||||||
var campaignRunning bool
|
campaignRunning := &atomic.Bool{}
|
||||||
// goroutine to vote for someone as scheduler! each participant must be
|
// goroutine to vote for someone as scheduler! each participant must be
|
||||||
// able to run this or nobody will be around to vote if others are down
|
// able to run this or nobody will be around to vote if others are down
|
||||||
campaignFunc := func() {
|
campaignFunc := func() {
|
||||||
@@ -363,18 +364,18 @@ func Schedule(client *etcd.Client, path string, hostname string, opts ...Option)
|
|||||||
//}
|
//}
|
||||||
if elected != hostname { // not me!
|
if elected != hostname { // not me!
|
||||||
// start up the campaign function
|
// start up the campaign function
|
||||||
if !campaignRunning {
|
if !campaignRunning.Load() {
|
||||||
campaignClose = make(chan struct{})
|
campaignClose = make(chan struct{})
|
||||||
campaignFunc() // run
|
campaignFunc() // run
|
||||||
campaignRunning = true
|
campaignRunning.Store(true)
|
||||||
}
|
}
|
||||||
continue // someone else does the scheduling...
|
continue // someone else does the scheduling...
|
||||||
} else { // campaigning while i am it loops fast
|
} else { // campaigning while i am it loops fast
|
||||||
// shutdown the campaign function
|
// shutdown the campaign function
|
||||||
if campaignRunning {
|
if campaignRunning.Load() { // XXX: RACE READ
|
||||||
close(campaignClose)
|
close(campaignClose)
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
campaignRunning = false
|
campaignRunning.Store(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,10 +560,10 @@ func Schedule(client *etcd.Client, path string, hostname string, opts ...Option)
|
|||||||
leaderResult, err := election.Leader(ctx)
|
leaderResult, err := election.Leader(ctx)
|
||||||
if err == concurrency.ErrElectionNoLeader {
|
if err == concurrency.ErrElectionNoLeader {
|
||||||
// start up the campaign function
|
// start up the campaign function
|
||||||
if !campaignRunning {
|
if !campaignRunning.Load() {
|
||||||
campaignClose = make(chan struct{})
|
campaignClose = make(chan struct{})
|
||||||
campaignFunc() // run
|
campaignFunc() // run
|
||||||
campaignRunning = true
|
campaignRunning.Store(true) // XXX: RACE WRITE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if options.debug {
|
if options.debug {
|
||||||
|
|||||||
Reference in New Issue
Block a user