From 482e086d54454bf9fec98b3613d32ffe525d7aa1 Mon Sep 17 00:00:00 2001 From: Preetha Appan Date: Fri, 31 Aug 2018 10:59:48 -0500 Subject: [PATCH 1/2] Use eval broker lock when reading/modifying delay heap --- nomad/eval_broker.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nomad/eval_broker.go b/nomad/eval_broker.go index 54e32e7a8..83a8c774c 100644 --- a/nomad/eval_broker.go +++ b/nomad/eval_broker.go @@ -763,8 +763,8 @@ func (b *EvalBroker) runDelayedEvalsWatcher(ctx context.Context) { return case <-timerChannel: // remove from the heap since we can enqueue it now - b.delayHeap.Remove(&evalWrapper{eval}) b.l.Lock() + b.delayHeap.Remove(&evalWrapper{eval}) b.stats.TotalWaiting -= 1 b.enqueueLocked(eval, eval.Type) b.l.Unlock() @@ -777,12 +777,14 @@ func (b *EvalBroker) runDelayedEvalsWatcher(ctx context.Context) { // nextDelayedEval returns the next delayed eval to launch and when it should be enqueued. // This peeks at the heap to return the top. If the heap is empty, this returns nil and zero time. func (b *EvalBroker) nextDelayedEval() (*structs.Evaluation, time.Time) { + b.l.Lock() // If there is nothing wait for an update. if b.delayHeap.Length() == 0 { + b.l.Unlock() return nil, time.Time{} } nextEval := b.delayHeap.Peek() - + b.l.Unlock() if nextEval == nil { return nil, time.Time{} } From 2d1c9d2a99cf0e5fae0728b229db89ef7c3cc9f0 Mon Sep 17 00:00:00 2001 From: Preetha Appan Date: Tue, 4 Sep 2018 11:45:05 -0500 Subject: [PATCH 2/2] Use readlock --- nomad/eval_broker.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nomad/eval_broker.go b/nomad/eval_broker.go index 83a8c774c..77de255a4 100644 --- a/nomad/eval_broker.go +++ b/nomad/eval_broker.go @@ -777,14 +777,14 @@ func (b *EvalBroker) runDelayedEvalsWatcher(ctx context.Context) { // nextDelayedEval returns the next delayed eval to launch and when it should be enqueued. // This peeks at the heap to return the top. If the heap is empty, this returns nil and zero time. func (b *EvalBroker) nextDelayedEval() (*structs.Evaluation, time.Time) { - b.l.Lock() + b.l.RLock() // If there is nothing wait for an update. if b.delayHeap.Length() == 0 { - b.l.Unlock() + b.l.RUnlock() return nil, time.Time{} } nextEval := b.delayHeap.Peek() - b.l.Unlock() + b.l.RUnlock() if nextEval == nil { return nil, time.Time{} }