Merge pull request #1777 from vieux/remove_refresh_networks

remove refresh networks from cluster to improve perfs
This commit is contained in:
Alexandre Beslic 2016-02-11 15:47:44 -08:00
commit 3c044d045c
2 changed files with 74 additions and 32 deletions

View File

@ -436,12 +436,35 @@ func (e *Engine) RemoveImage(image *Image, name string, force bool) ([]*dockercl
} }
// RemoveNetwork deletes a network from the engine. // RemoveNetwork removes a network from the engine.
func (e *Engine) RemoveNetwork(network *Network) error { func (e *Engine) RemoveNetwork(network *Network) error {
err := e.client.RemoveNetwork(network.ID) err := e.client.RemoveNetwork(network.ID)
e.CheckConnectionErr(err) e.CheckConnectionErr(err)
e.RefreshNetworks() if err != nil {
return err return err
}
// Remove the container from the state. Eventually, the state refresh loop
// will rewrite this.
e.DeleteNetwork(network)
return nil
}
// DeleteNetwork deletes a network from the internal engine state.
func (e *Engine) DeleteNetwork(network *Network) {
e.Lock()
delete(e.networks, network.ID)
e.Unlock()
}
// AddNetwork adds a network to the internal engine state.
func (e *Engine) AddNetwork(network *Network) {
e.Lock()
e.networks[network.ID] = &Network{
NetworkResource: network.NetworkResource,
Engine: e,
}
e.Unlock()
} }
// RemoveVolume deletes a volume from the engine. // RemoveVolume deletes a volume from the engine.
@ -913,22 +936,41 @@ func (e *Engine) String() string {
func (e *Engine) handler(ev *dockerclient.Event, _ chan error, args ...interface{}) { func (e *Engine) handler(ev *dockerclient.Event, _ chan error, args ...interface{}) {
// Something changed - refresh our internal state. // Something changed - refresh our internal state.
switch ev.Status {
case "pull", "untag", "delete", "commit": switch ev.Type {
// These events refer to images so there's no need to update case "network":
// containers. e.RefreshNetworks()
case "volume":
e.RefreshVolumes()
case "image":
e.RefreshImages() e.RefreshImages()
case "die", "kill", "oom", "pause", "start", "stop", "unpause", "rename": case "container":
// If the container state changes, we have to do an inspect in switch ev.Action {
// order to update container.Info and get the new NetworkSettings. case "die", "kill", "oom", "pause", "start", "stop", "unpause", "rename":
e.refreshContainer(ev.ID, true) e.refreshContainer(ev.ID, true)
e.RefreshVolumes() default:
e.RefreshNetworks() e.refreshContainer(ev.ID, false)
default: }
// Otherwise, do a "soft" refresh of the container. case "":
e.refreshContainer(ev.ID, false) // docker < 1.10
e.RefreshVolumes() switch ev.Status {
e.RefreshNetworks() case "pull", "untag", "delete", "commit":
// These events refer to images so there's no need to update
// containers.
e.RefreshImages()
case "die", "kill", "oom", "pause", "start", "stop", "unpause", "rename":
// If the container state changes, we have to do an inspect in
// order to update container.Info and get the new NetworkSettings.
e.refreshContainer(ev.ID, true)
e.RefreshVolumes()
e.RefreshNetworks()
default:
// Otherwise, do a "soft" refresh of the container.
e.refreshContainer(ev.ID, false)
e.RefreshVolumes()
e.RefreshNetworks()
}
} }
// If there is no event handler registered, abort right now. // If there is no event handler registered, abort right now.

View File

@ -216,7 +216,11 @@ func (c *Cluster) RemoveContainer(container *cluster.Container, force, volumes b
// RemoveNetwork removes a network from the cluster // RemoveNetwork removes a network from the cluster
func (c *Cluster) RemoveNetwork(network *cluster.Network) error { func (c *Cluster) RemoveNetwork(network *cluster.Network) error {
err := network.Engine.RemoveNetwork(network) err := network.Engine.RemoveNetwork(network)
c.refreshNetworks() if err == nil && network.Scope == "global" {
for _, engine := range c.engines {
engine.DeleteNetwork(network)
}
}
return err return err
} }
@ -434,18 +438,6 @@ func (c *Cluster) RemoveImages(name string, force bool) ([]*dockerclient.ImageDe
return out, err return out, err
} }
func (c *Cluster) refreshNetworks() {
var wg sync.WaitGroup
for _, e := range c.engines {
wg.Add(1)
go func(e *cluster.Engine) {
e.RefreshNetworks()
wg.Done()
}(e)
}
wg.Wait()
}
func (c *Cluster) refreshVolumes() { func (c *Cluster) refreshVolumes() {
var wg sync.WaitGroup var wg sync.WaitGroup
for _, e := range c.engines { for _, e := range c.engines {
@ -477,7 +469,15 @@ func (c *Cluster) CreateNetwork(request *dockerclient.NetworkCreate) (response *
} }
if nodes != nil { if nodes != nil {
resp, err := c.engines[nodes[0].ID].CreateNetwork(request) resp, err := c.engines[nodes[0].ID].CreateNetwork(request)
c.refreshNetworks() if err == nil {
if network := c.engines[nodes[0].ID].Networks().Get(resp.ID); network != nil && network.Scope == "global" {
for id, engine := range c.engines {
if id != nodes[0].ID {
engine.AddNetwork(network)
}
}
}
}
return resp, err return resp, err
} }
return nil, nil return nil, nil