20200: Add limiter for log create requests
[arvados.git] / sdk / go / arvados / client.go
index b400a8474e50a448ae2b6aa9f948711a8566823a..05176214ae1eb188fd4c8a0113b76e115f095a99 100644 (file)
@@ -23,6 +23,7 @@ import (
        "os"
        "regexp"
        "strings"
+       "sync/atomic"
        "time"
 
        "git.arvados.org/arvados.git/sdk/go/httpserver"
@@ -81,7 +82,9 @@ type Client struct {
        // differs from an outgoing connection limit (a feature
        // provided by http.Transport) when concurrent calls are
        // multiplexed on a single http2 connection.
-       requestLimiter
+       requestLimiter requestLimiter
+
+       last503 atomic.Value
 }
 
 // InsecureHTTPClient is the default http.Client used by a Client with
@@ -274,7 +277,9 @@ func (c *Client) Do(req *http.Request) (*http.Response, error) {
        }
 
        resp, err := c.httpClient().Do(req)
-       c.requestLimiter.Report(resp, err)
+       if c.requestLimiter.Report(resp, err) {
+               c.last503.Store(time.Now())
+       }
        if err == nil {
                // We need to call cancel() eventually, but we can't
                // use "defer cancel()" because the context has to
@@ -287,6 +292,13 @@ func (c *Client) Do(req *http.Request) (*http.Response, error) {
        return resp, err
 }
 
+// Last503 returns the time of the most recent HTTP 503 (Service
+// Unavailable) response. Zero time indicates never.
+func (c *Client) Last503() time.Time {
+       t, _ := c.last503.Load().(time.Time)
+       return t
+}
+
 // cancelOnClose calls a provided CancelFunc when its wrapped
 // ReadCloser's Close() method is called.
 type cancelOnClose struct {