Skip to content

Commit 0ec11c3

Browse files
authored
Merge pull request #1485 from SebTardif/fix-roundtripper-stacking
Move retryingRoundTripper wrapping to constructor
2 parents 6976478 + 3f79f3f commit 0ec11c3

2 files changed

Lines changed: 29 additions & 4 deletions

File tree

internal/kube/client.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ func NewMemoryRESTClientGetter(cfg *rest.Config, opts ...Option) *MemoryRESTClie
112112
opts(g)
113113
}
114114
g.setDefaults()
115+
// Add retries to fix temporary "etcdserver: leader changed" errors from kube-apiserver.
116+
// Done here once rather than in ToRESTConfig to avoid stacking wrappers on repeated calls.
117+
g.cfg.Wrap(func(rt http.RoundTripper) http.RoundTripper {
118+
return &retryingRoundTripper{wrapped: rt}
119+
})
115120
return g
116121
}
117122

@@ -131,10 +136,6 @@ func (c *MemoryRESTClientGetter) ToRESTConfig() (*rest.Config, error) {
131136
if c.cfg == nil {
132137
return nil, fmt.Errorf("MemoryRESTClientGetter has no REST config")
133138
}
134-
// add retries to fix temporary "etcdserver: leader changed" errors from kube-apiserver
135-
c.cfg.Wrap(func(rt http.RoundTripper) http.RoundTripper {
136-
return &retryingRoundTripper{wrapped: rt}
137-
})
138139
return c.cfg, nil
139140
}
140141

internal/kube/client_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,30 @@ func TestMemoryRESTClientGetter_ToRESTConfig(t *testing.T) {
184184
g.Expect(cfg).To(BeIdenticalTo(c.cfg))
185185
})
186186

187+
t.Run("wraps transport only once across multiple calls", func(t *testing.T) {
188+
g := NewWithT(t)
189+
190+
c := NewMemoryRESTClientGetter(&rest.Config{
191+
Host: "https://example.com",
192+
})
193+
194+
// Call ToRESTConfig multiple times.
195+
for i := 0; i < 10; i++ {
196+
_, err := c.ToRESTConfig()
197+
g.Expect(err).ToNot(HaveOccurred())
198+
}
199+
200+
// Verify that only one retryingRoundTripper layer exists by
201+
// walking the WrapTransport chain.
202+
rt := c.cfg.WrapTransport(nil)
203+
_, ok := rt.(*retryingRoundTripper)
204+
g.Expect(ok).To(BeTrue(), "expected retryingRoundTripper")
205+
206+
inner := rt.(*retryingRoundTripper).wrapped
207+
_, nested := inner.(*retryingRoundTripper)
208+
g.Expect(nested).To(BeFalse(), "transport should not be wrapped more than once")
209+
})
210+
187211
t.Run("error on nil REST config", func(t *testing.T) {
188212
g := NewWithT(t)
189213

0 commit comments

Comments
 (0)