diff --git a/src/commands/cmd_list.cc b/src/commands/cmd_list.cc index 2063347b379..a296a872981 100644 --- a/src/commands/cmd_list.cc +++ b/src/commands/cmd_list.cc @@ -165,16 +165,16 @@ class CommandBPop : public Commander, ~CommandBPop() override = default; Status Parse(const std::vector &args) override { - auto parse_result = ParseInt(args[args.size() - 1], 10); + auto parse_result = ParseFloat(args[args.size() - 1]); if (!parse_result) { - return {Status::RedisParseErr, "timeout is not an integer or out of range"}; + return {Status::RedisParseErr, errTimeoutIsNotFloat}; } if (*parse_result < 0) { return {Status::RedisParseErr, "timeout should not be negative"}; } - timeout_ = *parse_result; + timeout_ = static_cast(*parse_result * 1000 * 1000); keys_ = std::vector(args.begin() + 1, args.end() - 1); return Commander::Parse(args); @@ -203,7 +203,9 @@ class CommandBPop : public Commander, if (timeout_) { timer_.reset(NewTimer(bufferevent_get_base(bev))); - timeval tm = {timeout_, 0}; + int64_t timeout_second = timeout_ / 1000 / 1000; + int64_t timeout_microsecond = timeout_ % (1000 * 1000); + timeval tm = {timeout_second, static_cast(timeout_microsecond)}; evtimer_add(timer_.get(), &tm); } @@ -284,7 +286,7 @@ class CommandBPop : public Commander, private: bool left_ = false; - int timeout_ = 0; // seconds + int64_t timeout_ = 0; // microseconds std::vector keys_; Server *svr_ = nullptr; Connection *conn_ = nullptr; diff --git a/src/commands/cmd_zset.cc b/src/commands/cmd_zset.cc index 07ada2a019a..35a6a6ca840 100644 --- a/src/commands/cmd_zset.cc +++ b/src/commands/cmd_zset.cc @@ -300,14 +300,14 @@ class CommandBZPop : public Commander, explicit CommandBZPop(bool min) : min_(min) {} Status Parse(const std::vector &args) override { - auto parse_result = ParseInt(args[args.size() - 1], 10); + auto parse_result = ParseFloat(args[args.size() - 1]); if (!parse_result) { - return {Status::RedisParseErr, "timeout is not an integer or out of range"}; + return {Status::RedisParseErr, errTimeoutIsNotFloat}; } if (*parse_result < 0) { return {Status::RedisParseErr, errTimeoutIsNegative}; } - timeout_ = *parse_result; + timeout_ = static_cast(*parse_result * 1000 * 1000); keys_ = std::vector(args.begin() + 1, args.end() - 1); return Commander::Parse(args); @@ -346,7 +346,9 @@ class CommandBZPop : public Commander, if (timeout_) { timer_.reset(NewTimer(bufferevent_get_base(bev))); - timeval tm = {timeout_, 0}; + int64_t timeout_second = timeout_ / 1000 / 1000; + int64_t timeout_microsecond = timeout_ % (1000 * 1000); + timeval tm = {timeout_second, static_cast(timeout_microsecond)}; evtimer_add(timer_.get(), &tm); } @@ -420,7 +422,7 @@ class CommandBZPop : public Commander, private: bool min_; - int timeout_; + int64_t timeout_ = 0; // microseconds std::vector keys_; Server *svr_ = nullptr; Connection *conn_ = nullptr; @@ -522,7 +524,7 @@ class CommandBZMPop : public Commander, Status Parse(const std::vector &args) override { CommandParser parser(args, 1); - timeout_ = GET_OR_RET(parser.TakeInt(NumericRange{0, std::numeric_limits::max()})); + timeout_ = static_cast(GET_OR_RET(parser.TakeFloat()) * 1000 * 1000); if (timeout_ < 0) { return {Status::RedisParseErr, errTimeoutIsNegative}; } @@ -584,7 +586,9 @@ class CommandBZMPop : public Commander, if (timeout_) { timer_.reset(NewTimer(bufferevent_get_base(bev))); - timeval tm = {timeout_, 0}; + int64_t timeout_second = timeout_ / 1000 / 1000; + int64_t timeout_microsecond = timeout_ % (1000 * 1000); + timeval tm = {timeout_second, static_cast(timeout_microsecond)}; evtimer_add(timer_.get(), &tm); } @@ -651,7 +655,7 @@ class CommandBZMPop : public Commander, } private: - int timeout_ = 0; // seconds + int64_t timeout_ = 0; // microseconds int num_keys_; std::vector keys_; enum { ZSET_MIN, ZSET_MAX, ZSET_NONE } flag_ = ZSET_NONE; diff --git a/src/commands/error_constants.h b/src/commands/error_constants.h index 94858289c06..6311c2b77f1 100644 --- a/src/commands/error_constants.h +++ b/src/commands/error_constants.h @@ -32,6 +32,7 @@ inline constexpr const char *errNoSuchKey = "no such key"; inline constexpr const char *errUnbalancedStreamList = "Unbalanced XREAD list of streams: for each stream key an ID or '$' must be specified."; inline constexpr const char *errTimeoutIsNegative = "timeout is negative"; +inline constexpr const char *errTimeoutIsNotFloat = "timeout is not a float or out of range"; inline constexpr const char *errLimitIsNegative = "LIMIT can't be negative"; inline constexpr const char *errLimitOptionNotAllowed = "syntax error, LIMIT cannot be used without the special ~ option";