diff --git a/README.md b/README.md index 3b06170..42a0365 100644 --- a/README.md +++ b/README.md @@ -15,20 +15,25 @@ For full example see [this section](#example) *Parameters:* -| Name | Format | Description | -|--------------------|--------------------------|-------------------------------------------------------------------------------------------------------------------------------| -| tag | string | Select endpoints only with this tag | -| healthy | true/false | Return only endpoints which pass all health-checks. Default: false | -| wait | as in time.ParseDuration | Wait time for watch changes. Due this time period endpoints will be force refreshed. Default: inherits agent property | -| insecure | true/false | Allow insecure communication with Consul. Default: true | -| near | string | Sort endpoints by response duration. Can be efficient combine with `limit` parameter default: "_agent" | -| limit | int | Limit number of endpoints for the service. Default: no limit | -| timeout | as in time.ParseDuration | Http-client timeout. Default: 60s | -| max-backoff | as in time.ParseDuration | Max backoff time for reconnect to consul. Reconnects will start from 10ms to _max-backoff_ exponentialy with factor 2. Default: 1s | -| token | string | Consul token | -| dc | string | Consul datacenter to choose. Optional | -| allow-stale | true/false | Allow stale results from the agent. https://www.consul.io/api/features/consistency.html#stale | -| require-consistent | true/false | RequireConsistent forces the read to be fully consistent. This is more expensive but prevents ever performing a stale read. | +| Name | Format | Description | +|-------------------------|--------------------------|-------------------------------------------------------------------------------------------------------------------------------------| +| tag | string | Select endpoints only with this tag | +| healthy | true/false | Return only endpoints which pass all health-checks. Default: false | +| wait | as in time.ParseDuration | Wait time for watch changes. Due this time period endpoints will be force refreshed. Default: inherits agent property | +| insecure | true/false | Allow insecure communication with Consul. Default: true | +| near | string | Sort endpoints by response duration. Can be efficient combine with `limit` parameter default: "_agent" | +| limit | int | Limit number of endpoints for the service. Default: no limit | +| timeout | as in time.ParseDuration | Http-client timeout. Default: 60s | +| max-backoff | as in time.ParseDuration | Max backoff time for reconnect to consul. Reconnects will start from 10ms to _max-backoff_ exponentialy with factor 2. Default: 1s | +| token | string | Consul token | +| dc | string | Consul datacenter to choose. Optional | +| allow-stale | true/false | Allow stale results from the agent. https://www.consul.io/api/features/consistency.html#stale | +| require-consistent | true/false | RequireConsistent forces the read to be fully consistent. This is more expensive but prevents ever performing a stale read. | +| max-idle-conns | int | Maximum number of idle connections. Default: 0 | +| idle-conn-timeout | as in time.ParseDuration | Maximum amount of time an idle (keep-alive) connection will remain idle before being closed. Default: 0s | +| disable-compression | true/false | Disable compression for connections to consul. Default: false | +| tls-handshake-timeout | as in time.ParseDuration | Maximum amount of time to wait for a TLS handshake to complete. Default: 0s | +| expect-continue-timeout | as in time.ParseDuration | Maximum amount of time to wait for a 100-continue response before sending the request body. Default: 0s | ## Example ```go diff --git a/target.go b/target.go index 703bbad..35086be 100644 --- a/target.go +++ b/target.go @@ -29,15 +29,22 @@ type target struct { Dc string `form:"dc"` AllowStale bool `form:"allow-stale"` RequireConsistent bool `form:"require-consistent"` - // TODO(mbobakov): custom parameters for the http-transport // TODO(mbobakov): custom parameters for the TLS subsystem + + // custom parameters for the http-transport + MaxIdleConns int `form:"max-idle-conns"` + IdleConnTimeout time.Duration `form:"idle-conn-timeout"` + DisableCompression bool `form:"disable-compression"` + TLSHandshakeTimeout time.Duration `form:"tls-handshake-timeout"` + ExpectContinueTimeout time.Duration `form:"expect-continue-timeout"` } func (t *target) String() string { return fmt.Sprintf("service='%s' healthy='%t' tag='%s'", t.Service, t.Healthy, t.Tag) } -// parseURL with parameters +// parseURL with parameters +// // see README.md for the actual format // URL schema will stay stable in the future for backward compatibility func parseURL(u string) (target, error) { @@ -75,6 +82,23 @@ func parseURL(u string) (target, error) { return tgt, nil } +// createHttpTransport returns a customized http.Transport based on the values stored in the target struct. +// The returned http.Transport has the following properties: +// - MaxIdleConns: maximum number of idle connections +// - IdleConnTimeout: maximum amount of time an idle (keep-alive) connection will remain idle before being closed +// - TLSHandshakeTimeout: maximum amount of time to wait for a TLS handshake to complete +// - ExpectContinueTimeout: maximum amount of time to wait for a 100-continue response before sending the request body +// - DisableCompression: whether to disable the compression of response bodies (gzip) +func (t *target) createHttpTransport() *http.Transport { + return &http.Transport{ + MaxIdleConns: t.MaxIdleConns, + IdleConnTimeout: t.IdleConnTimeout, + TLSHandshakeTimeout: t.TLSHandshakeTimeout, + ExpectContinueTimeout: t.ExpectContinueTimeout, + DisableCompression: t.DisableCompression, + } +} + // consulConfig returns config based on the parsed target. // It uses custom http-client. func (t *target) consulConfig() *api.Config { @@ -86,7 +110,8 @@ func (t *target) consulConfig() *api.Config { } // custom http.Client c := &http.Client{ - Timeout: t.Timeout, + Timeout: t.Timeout, + Transport: t.createHttpTransport(), } return &api.Config{ Address: t.Addr, diff --git a/target_test.go b/target_test.go index 8fd447c..2b94573 100644 --- a/target_test.go +++ b/target_test.go @@ -24,22 +24,29 @@ func Test_parseURL(t *testing.T) { }, false, }, - {"all-args", "consul://user:password@127.0.0.127:8555/my-service?wait=14s&near=host&insecure=true&limit=1&tag=production&token=test_token&max-backoff=2s&dc=xx&allow-stale=true&require-consistent=true", + {"all-params", "consul://user:password@127.0.0.127:8555/my-service?allow-stale=true&dc=yy&disable-compression=true&expect-continue-timeout=3s&healthy=true&idle-conn-timeout=10s&insecure=true&limit=5&max-backoff=2s&max-idle-conns=99&near=host&require-consistent=true&tag=production&timeout=11s&tls-handshake-timeout=5s&token=test_token&wait=14s", target{ - Addr: "127.0.0.127:8555", - User: "user", - Password: "password", - Service: "my-service", - Near: "host", - Wait: 14 * time.Second, - TLSInsecure: true, - Limit: 1, - Tag: "production", - Token: "test_token", - MaxBackoff: 2 * time.Second, - Dc: "xx", - AllowStale: true, - RequireConsistent: true, + Addr: "127.0.0.127:8555", + User: "user", + Password: "password", + Service: "my-service", + Wait: 14 * time.Second, + Timeout: 11 * time.Second, + MaxBackoff: 2 * time.Second, + Tag: "production", + Near: "host", + Limit: 5, + Healthy: true, + TLSInsecure: true, + Token: "test_token", + Dc: "yy", + AllowStale: true, + RequireConsistent: true, + MaxIdleConns: 99, + IdleConnTimeout: 10 * time.Second, + DisableCompression: true, + TLSHandshakeTimeout: 5 * time.Second, + ExpectContinueTimeout: 3 * time.Second, }, false, }, diff --git a/tests/client_test.go b/tests/client_test.go index ed1c460..d6dbb95 100644 --- a/tests/client_test.go +++ b/tests/client_test.go @@ -16,7 +16,7 @@ import ( "google.golang.org/grpc/grpclog" ) -func TestCLient(t *testing.T) { +func TestClient(t *testing.T) { logger := logrus.New() grpclog.SetLoggerV2(&grpcLog{logger})