Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 19 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
31 changes: 28 additions & 3 deletions target.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand All @@ -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,
Expand Down
37 changes: 22 additions & 15 deletions target_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
Expand Down
2 changes: 1 addition & 1 deletion tests/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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})

Expand Down