Change:
the newly refactored retry logic introduced in 1.22 by broke the thread safety of . According to Clayton, it's not a release blocker for 1.24. So the goal is to fix it in 1.25 and then back port all the way to 1.22. Please note that there are other members (not related to retry logic) of that are not thread safe depending on how different methods of a object is used from multiple go routines. Also, the comments on some of these methods and sections for retry logic can be improved: For instance, we may want to rename to and to . That would have helped bring this back into mental cache faster and possibly help some future refactorer. Maintain thread safety of
/sig api-machinery /assign
/triage accepted thanks Abu!
(follow-up for 1.25) /reopen
Reopened this issue. <detailsIn response to : (follow-up for 1.25) </details
more follow-ups: backport to 1.23, 1.22 update the godoc of client go to make thread safety obvious add a test that verifies client behavior in the presence of retries (such that the race detector should flag us).
The Kubernetes project currently lacks enough contributors to adequately respond to all issues and PRs. This bot triages issues and PRs according to the following rules: After 90d of inactivity, is applied After 30d of inactivity since was applied, is applied After 30d of inactivity since was applied, the issue is closed You can: Mark this issue or PR as fresh with Mark this issue or PR as rotten with Close this issue or PR with Offer to help out with [Issue Triage][1] Please send feedback to sig-contributor-experience at . /lifecycle stale [1]:
The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs. This bot triages issues and PRs according to the following rules: After 90d of inactivity, is applied After 30d of inactivity since was applied, is applied After 30d of inactivity since was applied, the issue is closed You can: Mark this issue or PR as fresh with Close this issue or PR with Offer to help out with [Issue Triage][1] Please send feedback to sig-contributor-experience at . /lifecycle rotten [1]:
/lifecycle frozen how important is it that this safety be restored? 1.22 is almost out of support so the window to restore threadsafety to this functionality is rapidly closing
The generated clients in will not exhibit this issue since the typed clients reuse a and create a object for every API call. One has to hand craft a object and reuse it to exhibit this issue. I don't know how much of a problem this is in real world, but I intend to restore it to its previous behavior. I was away from work for a while, I am back now and will work on the back port soon, if that is okay,
pick for 1.23 - I have a test that verifies the fix for 1.23, and a master PR for this as well

Discussion:
"reflect" "strings" "sync" <ins> "sync/atomic" </ins> "syscall" "testing" "time"

} } } <ins> func TestRequestConcurrencyWithRetry(t *testing.T) { var attempts int32 client := clientForFunc(func(req *http.Request) (*http.Response, error) { defer func() { atomic.AddInt32(&attempts, 1) }() // always send a retry-after response return &http.Response{ StatusCode: http.StatusInternalServerError, Header:     http.Header{"Retry-After": []string{"1"}}, }, nil }) req := &Request{ verb: "POST", c: &RESTClient{ content: defaultContentConfig(), Client:  client, }, backoff:    &noSleepBackOff{}, maxRetries: 9, // 10 attempts in total, including the first retryFn:    defaultRequestRetryFn, } concurrency := 20 wg := sync.WaitGroup{} wg.Add(concurrency) startCh := make(chan struct{}) for i := 0; i < concurrency; i++ { go func() { defer wg.Done() <-startCh req.Do(context.Background()) }() } close(startCh) wg.Wait() // we expect (concurrency*req.maxRetries+1) attempts to be recorded expected := concurrency * (req.maxRetries + 1) if atomic.LoadInt32(&attempts) != int32(expected) { t.Errorf("Expected attempts: %d, but got: %d", expected, attempts) } } </ins>