Skip to content

Commit 59f0fae

Browse files
committed
fix(log): increase coder rpcConnectTimeout to 30s (#313)
(cherry picked from commit 1490e8a)
1 parent 4002758 commit 59f0fae

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

log/coder.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ import (
1919
)
2020

2121
var (
22-
rpcConnectTimeout = 10 * time.Second
22+
// We set a relatively high connection timeout for the initial connection.
23+
// There is an unfortunate race between the envbuilder container starting and the
24+
// associated provisioner job completing.
25+
rpcConnectTimeout = 30 * time.Second
2326
logSendGracePeriod = 10 * time.Second
2427
minAgentAPIV2 = "v2.9"
2528
)

log/coder_internal_test.go

+49
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,55 @@ func TestCoder(t *testing.T) {
170170
require.ErrorIs(t, err, context.DeadlineExceeded)
171171
<-handlerDone
172172
})
173+
174+
// In this test, we validate that a 401 error on the initial connect
175+
// results in a retry. When envbuilder initially attempts to connect
176+
// using the Coder agent token, the workspace build may not yet have
177+
// completed.
178+
t.Run("V2Retry", func(t *testing.T) {
179+
t.Parallel()
180+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
181+
defer cancel()
182+
183+
token := uuid.NewString()
184+
done := make(chan struct{})
185+
handlerSend := make(chan int)
186+
handler := func(w http.ResponseWriter, r *http.Request) {
187+
t.Logf("test handler: %s", r.URL.Path)
188+
if r.URL.Path == "/api/v2/buildinfo" {
189+
w.Header().Set("Content-Type", "application/json")
190+
_, _ = w.Write([]byte(`{"version": "v2.9.0"}`))
191+
return
192+
}
193+
code := <-handlerSend
194+
t.Logf("test handler response: %d", code)
195+
w.WriteHeader(code)
196+
}
197+
srv := httptest.NewServer(http.HandlerFunc(handler))
198+
defer srv.Close()
199+
200+
u, err := url.Parse(srv.URL)
201+
require.NoError(t, err)
202+
var connectError error
203+
go func() {
204+
defer close(handlerSend)
205+
defer close(done)
206+
_, _, connectError = Coder(ctx, u, token)
207+
}()
208+
209+
// Initial: unauthorized
210+
handlerSend <- http.StatusUnauthorized
211+
// 2nd try: still unauthorized
212+
handlerSend <- http.StatusUnauthorized
213+
// 3rd try: authorized
214+
handlerSend <- http.StatusOK
215+
216+
cancel()
217+
218+
<-done
219+
require.ErrorContains(t, connectError, "failed to WebSocket dial")
220+
require.ErrorIs(t, connectError, context.Canceled)
221+
})
173222
}
174223

175224
type fakeLogDest struct {

0 commit comments

Comments
 (0)