diff --git a/client/client.go b/client/client.go index 9a1e8e1d04e..f107a4f740b 100644 --- a/client/client.go +++ b/client/client.go @@ -1904,7 +1904,6 @@ func (c *Client) AllocStateUpdated(alloc *structs.Allocation) { // allocSync is a long lived function that batches allocation updates to the // server. func (c *Client) allocSync() { - staggered := false syncTicker := time.NewTicker(allocSyncIntv) updates := make(map[string]*structs.Allocation) for { @@ -1933,19 +1932,23 @@ func (c *Client) allocSync() { } var resp structs.GenericResponse - if err := c.RPC("Node.UpdateAlloc", &args, &resp); err != nil { + err := c.RPC("Node.UpdateAlloc", &args, &resp) + if err != nil { + // Error updating allocations, do *not* clear + // updates and retry after backoff c.logger.Error("error updating allocations", "error", err) - syncTicker.Stop() - syncTicker = time.NewTicker(c.retryIntv(allocSyncRetryIntv)) - staggered = true - } else { - updates = make(map[string]*structs.Allocation) - if staggered { - syncTicker.Stop() - syncTicker = time.NewTicker(allocSyncIntv) - staggered = false - } + syncTicker.Reset(c.retryIntv(allocSyncRetryIntv)) + continue } + + // Successfully updated allocs, reset map and ticker. + // Always reset ticker to give loop time to receive + // alloc updates. If the RPC took the ticker interval + // we may call it in a tight loop before draining + // buffered updates. + updates = make(map[string]*structs.Allocation, len(updates)) + syncTicker.Stop() + syncTicker = time.NewTicker(allocSyncIntv) } } }