Skip to content

Commit

Permalink
BRPOP{LPUSH} timeout can be float since 6.0
Browse files Browse the repository at this point in the history
And it also makes the tests run faster.
  • Loading branch information
alicebob committed Nov 6, 2022
1 parent e70d444 commit 91a1770
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 29 deletions.
32 changes: 11 additions & 21 deletions cmd_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,28 +63,23 @@ func (m *Miniredis) cmdBXpop(c *server.Peer, cmd string, args []string, lr leftr
return
}

timeoutS := args[len(args)-1]
keys := args[:len(args)-1]

timeout, err := strconv.Atoi(timeoutS)
if err != nil {
setDirty(c)
c.WriteError(msgInvalidTimeout)
return
var opts struct {
keys []string
timeout time.Duration
}
if timeout < 0 {
setDirty(c)
c.WriteError(msgNegTimeout)

if ok := optDuration(c, args[len(args)-1], &opts.timeout); !ok {
return
}
opts.keys = args[:len(args)-1]

blocking(
m,
c,
time.Duration(timeout)*time.Second,
opts.timeout,
func(c *server.Peer, ctx *connCtx) bool {
db := m.db(ctx.selectedDB)
for _, key := range keys {
for _, key := range opts.keys {
if !db.exists(key) {
continue
}
Expand Down Expand Up @@ -882,23 +877,18 @@ func (m *Miniredis) cmdBrpoplpush(c *server.Peer, cmd string, args []string) {
var opts struct {
src string
dst string
timeout int
timeout time.Duration
}
opts.src = args[0]
opts.dst = args[1]
if ok := optIntErr(c, args[2], &opts.timeout, msgInvalidTimeout); !ok {
return
}
if opts.timeout < 0 {
setDirty(c)
c.WriteError(msgNegTimeout)
if ok := optDuration(c, args[2], &opts.timeout); !ok {
return
}

blocking(
m,
c,
time.Duration(opts.timeout)*time.Second,
opts.timeout,
func(c *server.Peer, ctx *connCtx) bool {
db := m.db(ctx.selectedDB)

Expand Down
14 changes: 7 additions & 7 deletions cmd_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1254,7 +1254,7 @@ func TestBrpop(t *testing.T) {
)
mustDo(t, c,
"BRPOP", "key", "inf",
proto.Error("ERR timeout is not a float or out of range"),
proto.Error("ERR timeout is negative"),
)
})
}
Expand Down Expand Up @@ -1320,11 +1320,11 @@ func TestBrpopTimeout(t *testing.T) {
ok(t, err)
defer c.Close()

got := goStrings(t, s, "BRPOP", "l1", "1")
got := goStrings(t, s, "BRPOP", "l1", "0.1")
select {
case have := <-got:
equals(t, proto.NilList, have)
case <-time.After(1500 * time.Millisecond):
case <-time.After(200 * time.Millisecond):
t.Error("BRPOP took too long")
}
}
Expand Down Expand Up @@ -1416,7 +1416,7 @@ func TestBlpop(t *testing.T) {
)
mustDo(t, c,
"BLPOP", "key", "inf",
proto.Error("ERR timeout is not a float or out of range"),
proto.Error("ERR timeout is negative"),
)
})
}
Expand Down Expand Up @@ -1479,7 +1479,7 @@ func TestBrpoplpush(t *testing.T) {
)
mustDo(t, c,
"BRPOPLPUSH", "key", "foo", "inf",
proto.Error("ERR timeout is not a float or out of range"),
proto.Error("ERR timeout is negative"),
)
mustDo(t, c,
"BRPOPLPUSH", "key", "foo", "1", "baz",
Expand Down Expand Up @@ -1524,11 +1524,11 @@ func TestBrpoplpushTimeout(t *testing.T) {
ok(t, err)
defer s.Close()

got := goStrings(t, s, "BRPOPLPUSH", "l1", "l2", "1")
got := goStrings(t, s, "BRPOPLPUSH", "l1", "l2", "0.1")
select {
case have := <-got:
equals(t, proto.NilList, have)
case <-time.After(1500 * time.Millisecond):
case <-time.After(200 * time.Millisecond):
t.Error("BRPOPLPUSH took too long")
}
}
Expand Down
5 changes: 4 additions & 1 deletion integration/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,8 @@ func TestBrpop(t *testing.T) {
testRaw(t, func(c *client) {
c.Do("LPUSH", "l", "one")
c.Do("BRPOP", "l", "1")
c.Do("BRPOP", "l", "0.1")
c.Error("negative", "BRPOP", "l", "inf")
c.Do("EXISTS", "l")

// transaction
Expand Down Expand Up @@ -487,7 +489,7 @@ func TestBlpop(t *testing.T) {
func TestBrpoplpush(t *testing.T) {
testRaw(t, func(c *client) {
c.Do("LPUSH", "l", "one")
c.Do("BRPOPLPUSH", "l", "l2", "1")
c.Do("BRPOPLPUSH", "l", "l2", "0.1")
c.Do("EXISTS", "l")
c.Do("EXISTS", "l2")
c.Do("LRANGE", "l", "0", "-1")
Expand All @@ -499,6 +501,7 @@ func TestBrpoplpush(t *testing.T) {
c.Error("wrong number", "BRPOPLPUSH", "l", "x")
c.Error("wrong number", "BRPOPLPUSH", "1")
c.Error("negative", "BRPOPLPUSH", "from", "to", "-1")
c.Error("negative", "BRPOPLPUSH", "from", "to", "inf")
c.Error("wrong number", "BRPOPLPUSH", "from", "to", "-1", "xxx")
})

Expand Down
19 changes: 19 additions & 0 deletions opts.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package miniredis

import (
"math"
"strconv"
"time"

"github.com/alicebob/miniredis/v2/server"
)
Expand All @@ -23,3 +25,20 @@ func optIntErr(c *server.Peer, src string, dest *int, errMsg string) bool {
*dest = n
return true
}

func optDuration(c *server.Peer, src string, dest *time.Duration) bool {
n, err := strconv.ParseFloat(src, 64)
if err != nil {
setDirty(c)
c.WriteError(msgInvalidTimeout)
return false
}
if n < 0 || math.IsInf(n, 0) {
setDirty(c)
c.WriteError(msgNegTimeout)
return false
}

*dest = time.Duration(n*1_000_000) * time.Microsecond
return true
}

0 comments on commit 91a1770

Please sign in to comment.