diff --git a/pwd/instance.go b/pwd/instance.go index e323ad8..9ab72c6 100644 --- a/pwd/instance.go +++ b/pwd/instance.go @@ -129,7 +129,13 @@ func (p *pwd) InstanceNew(session *types.Session, conf types.InstanceConfig) (*t func (p *pwd) InstanceExec(instance *types.Instance, cmd []string) (int, error) { defer observeAction("InstanceExec", time.Now()) - return p.docker(instance.SessionId).Exec(instance.Name, cmd) + + dockerClient, err := p.dockerFactory.GetForSession(instance.SessionId) + if err != nil { + log.Println(err) + return -1, err + } + return dockerClient.Exec(instance.Name, cmd) } func (p *pwd) InstanceAllowedImages() []string { diff --git a/pwd/pwd.go b/pwd/pwd.go index 4329092..2e16498 100644 --- a/pwd/pwd.go +++ b/pwd/pwd.go @@ -114,14 +114,6 @@ func (p *pwd) getProvisioner(t string) (provisioner.ProvisionerApi, error) { } } -func (p *pwd) docker(sessionId string) docker.DockerApi { - d, err := p.dockerFactory.GetForSession(sessionId) - if err != nil { - panic("Should not have got here. Session always need to be validated before calling this.") - } - return d -} - func (p *pwd) setGauges() { s, _ := p.storage.SessionCount() ses := float64(s) diff --git a/pwd/session.go b/pwd/session.go index 0f9265b..264fbc4 100644 --- a/pwd/session.go +++ b/pwd/session.go @@ -1,6 +1,7 @@ package pwd import ( + "context" "fmt" "log" "math" @@ -11,6 +12,8 @@ import ( "sync" "time" + "golang.org/x/sync/errgroup" + "github.com/play-with-docker/play-with-docker/config" "github.com/play-with-docker/play-with-docker/docker" "github.com/play-with-docker/play-with-docker/event" @@ -63,7 +66,11 @@ func (p *pwd) SessionNew(duration time.Duration, stack, stackName, imageName str log.Printf("NewSession id=[%s]\n", s.Id) - dockerClient := p.docker(s.Id) + dockerClient, err := p.dockerFactory.GetForSession(s.Id) + if err != nil { + // We assume we are out of capacity + return nil, fmt.Errorf("Out of capacity") + } u, _ := url.Parse(dockerClient.GetDaemonHost()) if u.Host == "" { s.Host = "localhost" @@ -113,22 +120,33 @@ func (p *pwd) SessionClose(s *types.Session) error { s = updatedSession log.Printf("Starting clean up of session [%s]\n", s.Id) + g, _ := errgroup.WithContext(context.Background()) for _, i := range s.Instances { - err := p.InstanceDelete(s, i) - if err != nil { - log.Println(err) - return err - } + i := i + g.Go(func() error { + return p.InstanceDelete(s, i) + }) } + err = g.Wait() + if err != nil { + log.Println(err) + return err + } + // Disconnect PWD daemon from the network - if err := p.docker(s.Id).DisconnectNetwork(config.L2ContainerName, s.Id); err != nil { + dockerClient, err := p.dockerFactory.GetForSession(s.Id) + if err != nil { + log.Println(err) + return err + } + if err := dockerClient.DisconnectNetwork(config.L2ContainerName, s.Id); err != nil { if !strings.Contains(err.Error(), "is not connected to the network") { log.Println("ERROR NETWORKING", err) return err } } log.Printf("Disconnected l2 from network [%s]\n", s.Id) - if err := p.docker(s.Id).DeleteNetwork(s.Id); err != nil { + if err := dockerClient.DeleteNetwork(s.Id); err != nil { if !strings.Contains(err.Error(), "not found") { log.Println(err) return err @@ -189,7 +207,14 @@ func (p *pwd) SessionDeployStack(s *types.Session) error { cmd := fmt.Sprintf("docker swarm init --advertise-addr eth0 && docker-compose -f %s pull && docker stack deploy -c %s %s", file, file, s.StackName) w := sessionBuilderWriter{sessionId: s.Id, event: p.event} - code, err := p.docker(s.Id).ExecAttach(i.Name, []string{"sh", "-c", cmd}, &w) + + dockerClient, err := p.dockerFactory.GetForSession(s.Id) + if err != nil { + log.Println(err) + return err + } + + code, err := dockerClient.ExecAttach(i.Name, []string{"sh", "-c", cmd}, &w) if err != nil { log.Printf("Error executing stack [%s]: %s\n", s.Stack, err) return err