make Allocator.Stop() idempotent and non-blocking
So that tests don't have to be careful about ensuring that allocators are stopped exactly once, or rely on the magic mesh.ChannelSize for non-blocking behaviour.
This commit is contained in:
1 parent
4d352d6eb1
commit
695babf7ba
1 file changed
+12
-7
+12
-7
@@ -46,6 +46,7 @@ type operation interface {
|
||||
// are used around data structures.
|
||||
type Allocator struct {
|
||||
actionChan chan<- func()
|
||||
stopChan chan<- struct{}
|
||||
ourName mesh.PeerName
|
||||
seed []mesh.PeerName // optional user supplied ring seed
|
||||
universe address.Range // superset of all ranges
|
||||
@@ -108,16 +109,20 @@ func NewAllocator(config Config) *Allocator {
|
||||
func (alloc *Allocator) Start() {
|
||||
alloc.loadPersistedData()
|
||||
actionChan := make(chan func(), mesh.ChannelSize)
|
||||
stopChan := make(chan struct{})
|
||||
alloc.actionChan = actionChan
|
||||
alloc.stopChan = stopChan
|
||||
alloc.ticker = time.NewTicker(tickInterval)
|
||||
go alloc.actorLoop(actionChan)
|
||||
go alloc.actorLoop(actionChan, stopChan)
|
||||
}
|
||||
|
||||
// Stop makes the actor routine exit, for test purposes ONLY because any
|
||||
// calls after this is processed will hang. Async.
|
||||
func (alloc *Allocator) Stop() {
|
||||
alloc.ticker.Stop()
|
||||
alloc.actionChan <- nil
|
||||
select {
|
||||
case alloc.stopChan <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
// Operation life cycle
|
||||
@@ -582,14 +587,14 @@ func (alloc *Allocator) SetInterfaces(gossip mesh.Gossip) {
|
||||
|
||||
// ACTOR server
|
||||
|
||||
func (alloc *Allocator) actorLoop(actionChan <-chan func()) {
|
||||
func (alloc *Allocator) actorLoop(actionChan <-chan func(), stopChan <-chan struct{}) {
|
||||
defer alloc.ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case action := <-actionChan:
|
||||
if action == nil {
|
||||
return
|
||||
}
|
||||
action()
|
||||
case <-stopChan:
|
||||
return
|
||||
case <-alloc.ticker.C:
|
||||
if alloc.awaitingConsensus {
|
||||
alloc.propose()
|
||||
|
||||
Reference in new issue
Block a user