Skip to content

Commit a7a5296

Browse files
committed
feat: shorten rueidislock validity if there is a shorter deadline in the context
Signed-off-by: Rueian <[email protected]>
1 parent d27df62 commit a7a5296

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

rueidislock/lock.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -151,18 +151,18 @@ func keyname(prefix, name string, i int32) string {
151151
return sb.String()
152152
}
153153

154-
func (m *locker) acquire(ctx context.Context, key, val string, deadline time.Time, force bool) (err error) {
154+
func (m *locker) acquire(ctx context.Context, key, val string, duration time.Duration, deadline time.Time, force bool) (err error) {
155155
ctx, cancel := context.WithTimeout(ctx, m.timeout)
156156
var resp rueidis.RedisResult
157157
if force {
158158
if m.setpx {
159-
resp = fcqms.Exec(ctx, m.client, []string{key}, []string{val, strconv.FormatInt(m.validity.Milliseconds(), 10)})
159+
resp = fcqms.Exec(ctx, m.client, []string{key}, []string{val, strconv.FormatInt(duration.Milliseconds(), 10)})
160160
} else {
161161
resp = fcqat.Exec(ctx, m.client, []string{key}, []string{val, strconv.FormatInt(deadline.UnixMilli(), 10)})
162162
}
163163
} else {
164164
if m.setpx {
165-
resp = acqms.Exec(ctx, m.client, []string{key}, []string{val, strconv.FormatInt(m.validity.Milliseconds(), 10)})
165+
resp = acqms.Exec(ctx, m.client, []string{key}, []string{val, strconv.FormatInt(duration.Milliseconds(), 10)})
166166
} else {
167167
resp = acqat.Exec(ctx, m.client, []string{key}, []string{val, strconv.FormatInt(deadline.UnixMilli(), 10)})
168168
}
@@ -249,8 +249,15 @@ func (m *locker) try(ctx context.Context, cancel context.CancelFunc, name string
249249
var err error
250250

251251
val := random()
252-
deadline := time.Now().Add(m.validity)
253-
cacneltm := time.AfterFunc(m.validity, cancel)
252+
now := time.Now()
253+
duration := m.validity
254+
if dl, ok := ctx.Deadline(); ok {
255+
if dur := dl.Sub(now); dur < duration {
256+
duration = dur
257+
}
258+
}
259+
deadline := now.Add(duration)
260+
cacneltm := time.AfterFunc(duration, cancel)
254261
released := int32(0)
255262
acquired := int32(0)
256263
failures := int32(0)
@@ -314,7 +321,7 @@ func (m *locker) try(ctx context.Context, cancel context.CancelFunc, name string
314321
default:
315322
}
316323
if !errors.Is(err, ErrNotLocked) {
317-
if err = m.acquire(ctx, key, val, deadline, force); force && err == nil {
324+
if err = m.acquire(ctx, key, val, duration, deadline, force); force && err == nil {
318325
m.mu.RLock()
319326
if m.gates != nil {
320327
select {

rueidislock/lock_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,39 @@ func TestLocker_WithContext_CancelContext(t *testing.T) {
446446
}
447447
}
448448

449+
func TestLocker_WithContext_ShorterTimeoutContext(t *testing.T) {
450+
test := func(t *testing.T, noLoop, setpx, nocsc bool) {
451+
locker := newLocker(t, noLoop, setpx, nocsc)
452+
locker.validity = time.Second * 5
453+
locker.interval = time.Second * 3
454+
defer locker.Close()
455+
456+
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
457+
defer cancel()
458+
459+
ctx, cancel, err := locker.WithContext(ctx, strconv.Itoa(rand.Int()))
460+
if err != nil {
461+
t.Fatal(err)
462+
}
463+
time.Sleep(time.Second * 2)
464+
if !errors.Is(ctx.Err(), context.DeadlineExceeded) {
465+
t.Fatalf("unexpected context canceled %v", ctx.Err())
466+
}
467+
cancel()
468+
}
469+
for _, nocsc := range []bool{false, true} {
470+
t.Run("Tracking Loop", func(t *testing.T) {
471+
test(t, false, false, nocsc)
472+
})
473+
t.Run("Tracking NoLoop", func(t *testing.T) {
474+
test(t, true, false, nocsc)
475+
})
476+
t.Run("SET PX", func(t *testing.T) {
477+
test(t, true, true, nocsc)
478+
})
479+
}
480+
}
481+
449482
func TestLocker_TryWithContext(t *testing.T) {
450483
test := func(t *testing.T, noLoop, setpx, nocsc bool) {
451484
locker := newLocker(t, noLoop, setpx, nocsc)

0 commit comments

Comments
 (0)