cluster: Renew the context after communicating with the registry

When pinning by digest, the registry might be slow or unresponsive. This
could cause the context to already be expired by the time UpdateService
or CreateService is called. We want digest pinning to be a best-effort
operation, so it's problematic if a slow or misbehaving registry
prevents the service operation from completing. Replace the context
after communicating with the registry, so we have a fresh timeout for
the gRPC call.

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
(cherry picked from commit f8273a216e)
This commit is contained in:
Aaron Lehmann
2017-03-06 16:05:56 -08:00
parent 59c6eb8c2f
commit 161b2a50c3
2 changed files with 21 additions and 0 deletions

View File

@@ -32,6 +32,7 @@ be found.
* Retry failed network allocations less aggressively [docker/swarmkit#2021](https://github.com/docker/swarmkit/pull/2021)
* Avoid network allocation for tasks that are no longer running [docker/swarmkit#2017](https://github.com/docker/swarmkit/pull/2017)
* Bookkeeping fixes inside network allocator allocator [docker/swarmkit#2019](https://github.com/docker/swarmkit/pull/2019) [docker/swarmkit#2020](https://github.com/docker/swarmkit/pull/2020)
* Avoid timing out service create or update when a registry is slow to respond [#31861](https://github.com/docker/docker/pull/31861)
### Windows

View File

@@ -1119,6 +1119,16 @@ func (c *Cluster) CreateService(s types.ServiceSpec, encodedAuth string) (*apity
} else {
logrus.Debugf("creating service using supplied digest reference %s", ctnr.Image)
}
// Replace the context with a fresh one.
// If we timed out while communicating with the
// registry, then "ctx" will already be expired, which
// would cause UpdateService below to fail. Reusing
// "ctx" could make it impossible to create a service
// if the registry is slow or unresponsive.
var newCancel func()
ctx, newCancel = c.getRequestContext()
defer newCancel()
}
r, err := c.client.CreateService(ctx, &swarmapi.CreateServiceRequest{Spec: &serviceSpec})
@@ -1230,6 +1240,16 @@ func (c *Cluster) UpdateService(serviceIDOrName string, version uint64, spec typ
} else {
logrus.Debugf("updating service using supplied digest reference %s", newCtnr.Image)
}
// Replace the context with a fresh one.
// If we timed out while communicating with the
// registry, then "ctx" will already be expired, which
// would cause UpdateService below to fail. Reusing
// "ctx" could make it impossible to create a service
// if the registry is slow or unresponsive.
var newCancel func()
ctx, newCancel = c.getRequestContext()
defer newCancel()
}
_, err = c.client.UpdateService(