Describe the bug
A blocking command with a 0.001 seconds timeout blocks indefinitely.
To reproduce
BLPOP key 0.001 is blocking indefinitely while it shouldn't.
Expected behavior
Command should time out.
Additional information
XREAD and XREADGROUP commands, that get their timeout in milliseconds, behave properly with a 1 ms timeout.
Comment From: madolson
Hey @gabiganam, can you share what system you are running on. On my M2 macbook BLPOP key 0.001 is not blocking indefinitely, and is correctly casting everything to 1 ms.
Comment From: igxlin
@madolson It is not casting correctly in my machine (Linux 6.1.1).
The 0.001 * 1000 is saved as 0xf.fffffffffffffffp-4 and is cast into 0.
Similarly, some other timeout is not correct.
0.002 * 1000 => 1
0.004 * 1000 => 3
0.008 * 1000 => 7
BTW, what is the expected behavior when the timeout is very small. Take it as zero or 1ms? Or reply "out of range"?
Comment From: madolson
I think the current assumption of "<0.001 rounds to 0" is probably the wrong assumption. I don't like throwing an error, that would be a pretty harsh breaking change. I think rounding "up" to the nearest 1ms sounds like the most reasonable.
0.002 * 1000 => 1
0.004 * 1000 => 3
0.008 * 1000 => 7
Yeah, that also kind of worries me. That inaccuracy stops really becoming an issue at larger values, but I would expect the couple of lower digits be "correct".
Comment From: madolson
As per the docs:
When BLPOP causes a client to block and a non-zero timeout is specified, the client will unblock returning a nil multi-bulk value when the specified timeout has expired without a push operation against at least one of the specified keys.
Comment From: igxlin
I think rounding "up" to the nearest 1ms sounds like the most reasonable.
I think then simply use ceill for the input timeout can work. The timeout smaller than 0.001 will be round up to 0.001. And the timeout like 0.002, 0.004 will be cast correctly.
Comment From: gabiganam
@madolson I've tried on several EC2 instance types, with both x86 and arm standard images.
IMO the important inaccuracy is in the case of 0.001 => 0 because it's becoming blocking indefinitely.
In any case, ceil will also work of course...
Comment From: gabiganam
Correct @igxlin, I've updated my PR accordingly: https://github.com/redis/redis/pull/11688/files