Skip to content

Commit b200f00

Browse files
committed
fix: use a mutex to sync concurrent writes
1 parent 0a18776 commit b200f00

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

internal/api/middleware.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"net/http"
88
"net/url"
99
"strings"
10+
"sync"
1011
"sync/atomic"
1112
"time"
1213

@@ -270,13 +271,18 @@ type timeoutResponseWriter struct {
270271
ctx context.Context
271272
w http.ResponseWriter
272273
wrote int32
274+
mu sync.Mutex
273275
}
274276

275277
func (t *timeoutResponseWriter) Header() http.Header {
278+
t.mu.Lock()
279+
defer t.mu.Unlock()
276280
return t.w.Header()
277281
}
278282

279283
func (t *timeoutResponseWriter) Write(bytes []byte) (int, error) {
284+
t.mu.Lock()
285+
defer t.mu.Unlock()
280286
if t.ctx.Err() == context.DeadlineExceeded {
281287
if atomic.LoadInt32(&t.wrote) == 0 {
282288
return 0, context.DeadlineExceeded
@@ -287,12 +293,14 @@ func (t *timeoutResponseWriter) Write(bytes []byte) (int, error) {
287293
// through
288294
}
289295

290-
atomic.AddInt32(&t.wrote, 1)
296+
t.wrote = 1
291297

292298
return t.w.Write(bytes)
293299
}
294300

295301
func (t *timeoutResponseWriter) WriteHeader(statusCode int) {
302+
t.mu.Lock()
303+
defer t.mu.Unlock()
296304
if t.ctx.Err() == context.DeadlineExceeded {
297305
if atomic.LoadInt32(&t.wrote) == 0 {
298306
return
@@ -303,7 +311,7 @@ func (t *timeoutResponseWriter) WriteHeader(statusCode int) {
303311
// through
304312
}
305313

306-
atomic.AddInt32(&t.wrote, 1)
314+
t.wrote = 1
307315

308316
t.w.WriteHeader(statusCode)
309317
}
@@ -324,8 +332,10 @@ func (a *API) timeoutMiddleware(timeout time.Duration) func(http.Handler) http.H
324332

325333
err := ctx.Err()
326334

335+
timeoutWriter.mu.Lock()
336+
defer timeoutWriter.mu.Unlock()
327337
if err == context.DeadlineExceeded {
328-
if atomic.LoadInt32(&timeoutWriter.wrote) == 0 {
338+
if timeoutWriter.wrote == 0 {
329339
// writer wasn't written to, so we're sending the error payload
330340

331341
httpError := &HTTPError{

0 commit comments

Comments
 (0)