Skip to content

Commit

Permalink
Merge pull request #2160 from buildkite/api-client-header-buildkite-t…
Browse files Browse the repository at this point in the history
…imeout-milliseconds

`Buildkite-Timeout-Milliseconds` request header
  • Loading branch information
pda authored Jun 21, 2023
2 parents 5cf6293 + d4ab148 commit 496484b
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
43 changes: 43 additions & 0 deletions api/api_internal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package api

import (
"context"
"strconv"
"testing"
"time"

"github.com/buildkite/agent/v3/logger"
"github.com/stretchr/testify/assert"
)

func TestNewRequestBuildkiteTimeoutMilliseconds(t *testing.T) {
c := NewClient(logger.NewBuffer(), Config{})

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

r, err := c.newRequest(ctx, "GET", "/foo", nil)
assert.NoError(t, err)

value := r.Header.Get("Buildkite-Timeout-Milliseconds")
ms, err := strconv.ParseInt(value, 10, 64)
assert.NoError(t, err)

// Allow a generous 1000ms between setting the timeout and the header being set.
if ms <= 9_000 || ms > 10_000 {
t.Errorf("Expected Buildkite-Timeout-Milliseconds to reflect 10 second timeout, got %q (%d ms)", value, ms)
}
}

func TestNewRequestWithoutBuildkiteTimeoutMilliseconds(t *testing.T) {
c := NewClient(logger.NewBuffer(), Config{})

ctx := context.Background() // no timeout/deadline

r, err := c.newRequest(ctx, "GET", "/foo", nil)
assert.NoError(t, err)

if value, ok := r.Header["Buildkite-Timeout-Milliseconds"]; ok {
t.Errorf("Expected no Buildkite-Timeout-Milliseconds header, got %q", value)
}
}
10 changes: 10 additions & 0 deletions api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"net/http/httputil"
"net/url"
"reflect"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -172,6 +173,15 @@ func (c *Client) newRequest(

req.Header.Add("User-Agent", c.conf.UserAgent)

// If our context has a timeout/deadline, tell the server how long is remaining.
// This may allow the server to configure its own timeouts accordingly.
if deadline, ok := ctx.Deadline(); ok {
ms := time.Until(deadline).Milliseconds()
if ms > 0 {
req.Header.Add("Buildkite-Timeout-Milliseconds", strconv.FormatInt(ms, 10))
}
}

for _, header := range headers {
req.Header.Add(header.Name, header.Value)
}
Expand Down

0 comments on commit 496484b

Please sign in to comment.