Pārlūkot izejas kodu

client: even cleaner use of Transport

First off, sorry for the noise. This is a cleaner step of #8508

Found more of a root cause of the open file handles.
After more testing I found that the open file descriptors will still
occur for TCP:// connections to the daemon, causing client and/or daemon
to fail.

The issue was instantiating a new http.Transport on _ever_ client
request. So each instance held the prior connection alive, but was only
ever used once.

By moving it out to the initilization of DockerCli, we can now have
reuse of idled connections. Simplifies the garbage overhead of the
client too, though that's not usually a deal.

Signed-off-by: Vincent Batts <vbatts@redhat.com>
Vincent Batts 10 gadi atpakaļ
vecāks
revīzija
da42ae536c
2 mainītis faili ar 19 papildinājumiem un 18 dzēšanām
  1. 18 0
      api/client/cli.go
  2. 1 18
      api/client/utils.go

+ 18 - 0
api/client/cli.go

@@ -5,10 +5,13 @@ import (
 	"encoding/json"
 	"encoding/json"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
+	"net"
+	"net/http"
 	"os"
 	"os"
 	"reflect"
 	"reflect"
 	"strings"
 	"strings"
 	"text/template"
 	"text/template"
+	"time"
 
 
 	flag "github.com/docker/docker/pkg/mflag"
 	flag "github.com/docker/docker/pkg/mflag"
 	"github.com/docker/docker/pkg/term"
 	"github.com/docker/docker/pkg/term"
@@ -34,6 +37,7 @@ type DockerCli struct {
 	isTerminalIn bool
 	isTerminalIn bool
 	// isTerminalOut describes if client's STDOUT is a TTY
 	// isTerminalOut describes if client's STDOUT is a TTY
 	isTerminalOut bool
 	isTerminalOut bool
+	transport     *http.Transport
 }
 }
 
 
 var funcMap = template.FuncMap{
 var funcMap = template.FuncMap{
@@ -131,6 +135,19 @@ func NewDockerCli(in io.ReadCloser, out, err io.Writer, key libtrust.PrivateKey,
 		err = out
 		err = out
 	}
 	}
 
 
+	// The transport is created here for reuse during the client session
+	tr := &http.Transport{
+		TLSClientConfig: tlsConfig,
+		Dial: func(dial_network, dial_addr string) (net.Conn, error) {
+			// Why 32? See issue 8035
+			return net.DialTimeout(proto, addr, 32*time.Second)
+		},
+	}
+	if proto == "unix" {
+		// no need in compressing for local communications
+		tr.DisableCompression = true
+	}
+
 	return &DockerCli{
 	return &DockerCli{
 		proto:         proto,
 		proto:         proto,
 		addr:          addr,
 		addr:          addr,
@@ -144,5 +161,6 @@ func NewDockerCli(in io.ReadCloser, out, err io.Writer, key libtrust.PrivateKey,
 		isTerminalOut: isTerminalOut,
 		isTerminalOut: isTerminalOut,
 		tlsConfig:     tlsConfig,
 		tlsConfig:     tlsConfig,
 		scheme:        scheme,
 		scheme:        scheme,
+		transport:     tr,
 	}
 	}
 }
 }

+ 1 - 18
api/client/utils.go

@@ -8,7 +8,6 @@ import (
 	"fmt"
 	"fmt"
 	"io"
 	"io"
 	"io/ioutil"
 	"io/ioutil"
-	"net"
 	"net/http"
 	"net/http"
 	"net/url"
 	"net/url"
 	"os"
 	"os"
@@ -16,7 +15,6 @@ import (
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
 	"syscall"
 	"syscall"
-	"time"
 
 
 	"github.com/docker/docker/api"
 	"github.com/docker/docker/api"
 	"github.com/docker/docker/dockerversion"
 	"github.com/docker/docker/dockerversion"
@@ -33,22 +31,7 @@ var (
 )
 )
 
 
 func (cli *DockerCli) HTTPClient() *http.Client {
 func (cli *DockerCli) HTTPClient() *http.Client {
-	tr := &http.Transport{
-		TLSClientConfig: cli.tlsConfig,
-		Dial: func(network, addr string) (net.Conn, error) {
-			// Why 32? See issue 8035
-			return net.DialTimeout(cli.proto, cli.addr, 32*time.Second)
-		},
-	}
-	if cli.proto == "unix" {
-		// XXX workaround for net/http Transport which caches connections, but is
-		// intended for tcp connections, not unix sockets.
-		tr.DisableKeepAlives = true
-
-		// no need in compressing for local communications
-		tr.DisableCompression = true
-	}
-	return &http.Client{Transport: tr}
+	return &http.Client{Transport: cli.transport}
 }
 }
 
 
 func (cli *DockerCli) encodeData(data interface{}) (*bytes.Buffer, error) {
 func (cli *DockerCli) encodeData(data interface{}) (*bytes.Buffer, error) {