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.
This commit is contained in:
Danielle Tomlinson
2018-12-12 16:30:01 +01:00
parent 1678a8499b
commit 875dd737cb

View File

@@ -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