From 875dd737cbe987bc92c5007880448d76f97ade75 Mon Sep 17 00:00:00 2001 From: Danielle Tomlinson Date: Wed, 12 Dec 2018 16:30:01 +0100 Subject: [PATCH] client: updateAlloc release lock after read The allocLock is used to synchronize access to the alloc runner map, not to ensure internal consistency of the alloc runners themselves. This updates the updateAlloc process to avoid hanging on to an exclusive lock of the map while applying changes to allocrunners themselves, as they should be internally consistent. This fixes a bug where any client allocation api will block during the shutdown or updating of an allocrunner and its child taskrunners. --- client/client.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/client.go b/client/client.go index f3565727b..229b62240 100644 --- a/client/client.go +++ b/client/client.go @@ -1996,9 +1996,9 @@ func (c *Client) removeAlloc(allocID string) { // updateAlloc is invoked when we should update an allocation func (c *Client) updateAlloc(update *structs.Allocation) { - c.allocLock.Lock() - defer c.allocLock.Unlock() + c.allocLock.RLock() ar, ok := c.allocs[update.ID] + c.allocLock.RUnlock() if !ok { c.logger.Warn("cannot update nonexistent alloc", "alloc_id", update.ID) return