From ae474e05f553c7abefc8674148e2a84a417bbf64 Mon Sep 17 00:00:00 2001 From: Danny Yates Date: Wed, 27 Nov 2013 12:18:01 +0000 Subject: [PATCH] Allow multiple clients to pull the same tag simultaneously If two clients simultaneously try to pull the same tag, there was a race whereby one would succeed and the second would generate an error. Now, the second simply waits for the first to complete. --- server.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/server.go b/server.go index a988d2133d..a5c91fa84e 100644 --- a/server.go +++ b/server.go @@ -985,8 +985,14 @@ func (srv *Server) ImagePull(localName string, tag string, out io.Writer, sf *ut if err != nil { return err } - if _, err := srv.poolAdd("pull", localName+":"+tag); err != nil { - return err + + out = utils.NewWriteFlusher(out) + + if c, err := srv.poolAdd("pull", localName+":"+tag); err != nil { + // Another pull of the same repository is already taking place; just wait for it to finish + out.Write(sf.FormatStatus("", "Repository %s already being pulled by another client. Waiting.", localName)) + <-c + return nil } defer srv.poolRemove("pull", localName+":"+tag) @@ -1001,7 +1007,6 @@ func (srv *Server) ImagePull(localName string, tag string, out io.Writer, sf *ut localName = remoteName } - out = utils.NewWriteFlusher(out) err = srv.pullRepository(r, out, localName, remoteName, tag, endpoint, sf, parallel) if err == registry.ErrLoginRequired { return err