Skip to content

Commit 8f6c30d

Browse files
authored
Merge pull request #18937 from ktalg/release-3.5
[3.5] fix runtime error: comparing uncomparable type
2 parents 601a884 + 83045bc commit 8f6c30d

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

client/v3/lease.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,12 @@ func (l *lessor) Leases(ctx context.Context) (*LeaseLeasesResponse, error) {
263263
return nil, ContextError(ctx, err)
264264
}
265265

266+
// To identify the context passed to `KeepAlive`, a key/value pair is
267+
// attached to the context. The key is a `keepAliveCtxKey` object, and
268+
// the value is the pointer to the context object itself, ensuring
269+
// uniqueness as each context has a unique memory address.
270+
type keepAliveCtxKey struct{}
271+
266272
func (l *lessor) KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAliveResponse, error) {
267273
ch := make(chan *LeaseKeepAliveResponse, LeaseResponseChSize)
268274

@@ -277,6 +283,10 @@ func (l *lessor) KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAl
277283
default:
278284
}
279285
ka, ok := l.keepAlives[id]
286+
287+
if ctx.Done() != nil {
288+
ctx = context.WithValue(ctx, keepAliveCtxKey{}, &ctx)
289+
}
280290
if !ok {
281291
// create fresh keep alive
282292
ka = &keepAlive{
@@ -347,7 +357,7 @@ func (l *lessor) keepAliveCtxCloser(ctx context.Context, id LeaseID, donec <-cha
347357

348358
// close channel and remove context if still associated with keep alive
349359
for i, c := range ka.ctxs {
350-
if c == ctx {
360+
if c.Value(keepAliveCtxKey{}) == ctx.Value(keepAliveCtxKey{}) {
351361
close(ka.chs[i])
352362
ka.ctxs = append(ka.ctxs[:i], ka.ctxs[i+1:]...)
353363
ka.chs = append(ka.chs[:i], ka.chs[i+1:]...)

tests/integration/clientv3/lease/lease_test.go

+28-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,14 @@ func TestLeaseKeepAlive(t *testing.T) {
133133
t.Errorf("failed to create lease %v", err)
134134
}
135135

136-
rc, kerr := lapi.KeepAlive(context.Background(), resp.ID)
136+
type uncomparableCtx struct {
137+
context.Context
138+
_ func()
139+
}
140+
141+
ctx, cancel := context.WithCancel(context.Background())
142+
defer cancel()
143+
rc, kerr := lapi.KeepAlive(uncomparableCtx{Context: ctx}, resp.ID)
137144
if kerr != nil {
138145
t.Errorf("failed to keepalive lease %v", kerr)
139146
}
@@ -151,6 +158,26 @@ func TestLeaseKeepAlive(t *testing.T) {
151158
t.Errorf("ID = %x, want %x", kresp.ID, resp.ID)
152159
}
153160

161+
ctx2, cancel2 := context.WithCancel(context.Background())
162+
rc2, kerr2 := lapi.KeepAlive(uncomparableCtx{Context: ctx2}, resp.ID)
163+
if kerr2 != nil {
164+
t.Errorf("failed to keepalive lease %v", kerr2)
165+
}
166+
167+
cancel2()
168+
169+
_, ok = <-rc2
170+
if ok {
171+
t.Errorf("chan is not closed, want cancel stop keepalive")
172+
}
173+
174+
select {
175+
case <-rc:
176+
// cancel2() should not affect first keepalive
177+
t.Errorf("chan is closed, want keepalive continue")
178+
default:
179+
}
180+
154181
lapi.Close()
155182

156183
_, ok = <-rc

0 commit comments

Comments
 (0)