summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabi Ganam <gabiganam@gmail.com>2023-01-08 11:02:48 +0200
committerOran Agra <oran@redislabs.com>2023-01-16 18:40:35 +0200
commit574a49b96c02f6833bef3b15501aafda1e0fb031 (patch)
tree1dd2ca191cb7371477fda86ad263c0bf49796cf5
parent61a1d4540de18b82f800bdfdc138057f7145451f (diff)
downloadredis-574a49b96c02f6833bef3b15501aafda1e0fb031.tar.gz
Blocking command with a 0.001 seconds timeout blocks indefinitely (#11688)
Any value in the range of [0-1) turns to 0 when being cast from double to long long. This change rounds up instead of down for values that can't be stored precisely as long doubles. (cherry picked from commit eef29b68a2cd94de1f03aa1b7891af75f5cabae2)
-rw-r--r--src/timeout.c4
-rw-r--r--tests/unit/type/list.tcl10
2 files changed, 13 insertions, 1 deletions
diff --git a/src/timeout.c b/src/timeout.c
index 36cea7c26..90d0fe796 100644
--- a/src/timeout.c
+++ b/src/timeout.c
@@ -29,6 +29,8 @@
#include "server.h"
#include "cluster.h"
+#include <math.h>
+
/* ========================== Clients timeouts ============================= */
/* Check if this blocked client timedout (does nothing if the client is
@@ -169,7 +171,7 @@ int getTimeoutFromObjectOrReply(client *c, robj *object, mstime_t *timeout, int
if (getLongDoubleFromObjectOrReply(c,object,&ftval,
"timeout is not a float or out of range") != C_OK)
return C_ERR;
- tval = (long long) (ftval * 1000.0);
+ tval = (long long) ceill(ftval * 1000.0);
} else {
if (getLongLongFromObjectOrReply(c,object,&tval,
"timeout is not an integer or out of range") != C_OK)
diff --git a/tests/unit/type/list.tcl b/tests/unit/type/list.tcl
index 3133923d6..0c52dd8f5 100644
--- a/tests/unit/type/list.tcl
+++ b/tests/unit/type/list.tcl
@@ -1256,6 +1256,16 @@ foreach {pop} {BLPOP BLMPOP_LEFT} {
$rd close
}
+ test "$pop: with 0.001 timeout should not block indefinitely" {
+ # Use a timeout of 0.001 and wait for the number of blocked clients to equal 0.
+ # Validate the empty read from the deferring client.
+ set rd [redis_deferring_client]
+ bpop_command $rd $pop blist1 0.001
+ wait_for_blocked_clients_count 0
+ assert_equal {} [$rd read]
+ $rd close
+ }
+
test "$pop: second argument is not a list" {
set rd [redis_deferring_client]
r del blist1{t} blist2{t}