X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/f69395a08509cc8c664c3256019d4d3cdb67db86..33606c82797185fa65751f5724304f02605e0e05:/sdk/go/keepclient/support.go diff --git a/sdk/go/keepclient/support.go b/sdk/go/keepclient/support.go index 1f2a976263..c24849e687 100644 --- a/sdk/go/keepclient/support.go +++ b/sdk/go/keepclient/support.go @@ -9,6 +9,7 @@ import ( "io" "io/ioutil" "log" + "net" "net/http" "os" "strings" @@ -27,21 +28,64 @@ func Md5String(s string) string { return fmt.Sprintf("%x", md5.Sum([]byte(s))) } +// Set timeouts apply when connecting to keepproxy services (assumed to be over +// the Internet). +func (this *KeepClient) setClientSettingsProxy() { + if this.Client.Timeout == 0 { + // Maximum time to wait for a complete response + this.Client.Timeout = 300 * time.Second + + // TCP and TLS connection settings + this.Client.Transport = &http.Transport{ + Dial: (&net.Dialer{ + // The maximum time to wait to set up + // the initial TCP connection. + Timeout: 30 * time.Second, + + // The TCP keep alive heartbeat + // interval. + KeepAlive: 120 * time.Second, + }).Dial, + + TLSHandshakeTimeout: 10 * time.Second, + } + } + +} + +// Set timeouts apply when connecting to keepstore services directly (assumed +// to be on the local network). +func (this *KeepClient) setClientSettingsStore() { + if this.Client.Timeout == 0 { + // Maximum time to wait for a complete response + this.Client.Timeout = 20 * time.Second + + // TCP and TLS connection timeouts + this.Client.Transport = &http.Transport{ + Dial: (&net.Dialer{ + // The maximum time to wait to set up + // the initial TCP connection. + Timeout: 2 * time.Second, + + // The TCP keep alive heartbeat + // interval. + KeepAlive: 180 * time.Second, + }).Dial, + + TLSHandshakeTimeout: 4 * time.Second, + } + } +} + func (this *KeepClient) DiscoverKeepServers() error { if prx := os.Getenv("ARVADOS_KEEP_PROXY"); prx != "" { sr := map[string]string{"proxy": prx} this.SetServiceRoots(sr) this.Using_proxy = true - if this.Client.Timeout == 0 { - this.Client.Timeout = 10 * time.Minute - } + this.setClientSettingsProxy() return nil } - if this.Client.Timeout == 0 { - this.Client.Timeout = 15 * time.Second - } - type svcList struct { Items []keepDisk `json:"items"` } @@ -78,6 +122,12 @@ func (this *KeepClient) DiscoverKeepServers() error { } } + if this.Using_proxy { + this.setClientSettingsProxy() + } else { + this.setClientSettingsStore() + } + this.SetServiceRoots(service_roots) return nil @@ -104,11 +154,17 @@ func (this KeepClient) uploadToKeepServer(host string, hash string, body io.Read return } - if expectedLength > -1 { - req.ContentLength = expectedLength - } - if expectedLength == 0 { - defer body.Close() + req.ContentLength = expectedLength + if expectedLength > 0 { + // http.Client.Do will close the body ReadCloser when it is + // done with it. + req.Body = body + } else { + // "For client requests, a value of 0 means unknown if Body is + // not nil." In this case we do want the body to be empty, so + // don't set req.Body. However, we still need to close the + // body ReadCloser. + body.Close() } req.Header.Add("Authorization", fmt.Sprintf("OAuth2 %s", this.Arvados.ApiToken)) @@ -118,8 +174,6 @@ func (this KeepClient) uploadToKeepServer(host string, hash string, body io.Read req.Header.Add(X_Keep_Desired_Replicas, fmt.Sprint(this.Want_replicas)) } - req.Body = body - var resp *http.Response if resp, err = this.Client.Do(req); err != nil { log.Printf("[%v] Upload failed %v error: %v", requestId, url, err.Error())