From b221baf4edeafec815ba725d0d6154d32b8d8fc9 Mon Sep 17 00:00:00 2001 From: Anton Tiurin Date: Wed, 8 Apr 2015 22:25:54 +0300 Subject: [PATCH 1/2] [SwarmCluster] Add RLock to Cluster.hasEngine Signed-off-by: Anton Tiurin --- cluster/swarm/cluster.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cluster/swarm/cluster.go b/cluster/swarm/cluster.go index cd83081133..d683f6285c 100644 --- a/cluster/swarm/cluster.go +++ b/cluster/swarm/cluster.go @@ -148,6 +148,9 @@ func (c *Cluster) newEntries(entries []*discovery.Entry) { } func (c *Cluster) hasEngine(addr string) bool { + c.RLock() + defer c.RUnlock() + for _, engine := range c.engines { if engine.Addr == addr { return true @@ -255,7 +258,7 @@ func (c *Cluster) listNodes() []*node.Node { c.RLock() defer c.RUnlock() - out := []*node.Node{} + out := make([]*node.Node, 0, len(c.engines)) for _, n := range c.engines { out = append(out, node.NewNode(n)) } @@ -268,7 +271,7 @@ func (c *Cluster) listEngines() []*cluster.Engine { c.RLock() defer c.RUnlock() - out := []*cluster.Engine{} + out := make([]*cluster.Engine, 0, len(c.engines)) for _, n := range c.engines { out = append(out, n) } From 2b4bbf1ef208ea2fc12e269b7822c9512efd4540 Mon Sep 17 00:00:00 2001 From: Anton Tiurin Date: Wed, 8 Apr 2015 22:30:23 +0300 Subject: [PATCH 2/2] [SwarmCluster] Add RLock to Cluster.Pull Use sync.WaitGroup (go-way) to wait for a collection of pulling goroutines. Signed-off-by: Anton Tiurin --- cluster/swarm/cluster.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/cluster/swarm/cluster.go b/cluster/swarm/cluster.go index d683f6285c..368f834e83 100644 --- a/cluster/swarm/cluster.go +++ b/cluster/swarm/cluster.go @@ -199,10 +199,15 @@ func (c *Cluster) RemoveImage(image *cluster.Image) ([]*dockerclient.ImageDelete // Pull is exported func (c *Cluster) Pull(name string, callback func(what, status string)) { - size := len(c.engines) - done := make(chan bool, size) + var wg sync.WaitGroup + + c.RLock() for _, n := range c.engines { + wg.Add(1) + go func(nn *cluster.Engine) { + defer wg.Done() + if callback != nil { callback(nn.Name, "") } @@ -214,12 +219,11 @@ func (c *Cluster) Pull(name string, callback func(what, status string)) { callback(nn.Name, "downloaded") } } - done <- true }(n) } - for i := 0; i < size; i++ { - <-done - } + c.RUnlock() + + wg.Wait() } // Containers returns all the containers in the cluster.