Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a98605f

Browse files
BLPOP with a float timeout
See #2157
1 parent b7bf22d commit a98605f

5 files changed

Lines changed: 46 additions & 28 deletions

File tree

redis.stub.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ public function bitop(string $operation, string $deskey, string $srckey, string
5252
/** @return int|Redis */
5353
public function bitpos(string $key, int $bit, int $start = 0, int $end = -1);
5454

55-
public function blPop(string|array $key, string|int $timeout_or_key, mixed ...$extra_args): array;
55+
public function blPop(string|array $key, string|double|int $timeout_or_key, mixed ...$extra_args): array;
5656

57-
public function brPop(string|array $key, string|int $timeout_or_key, mixed ...$extra_args): array;
57+
public function brPop(string|array $key, string|double|int $timeout_or_key, mixed ...$extra_args): array;
5858

5959
public function brpoplpush(string $src, string $dst, int $timeout): string;
6060

redis_arginfo.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 2b1fc18e5c464c551df8572363972769b2ec1096 */
2+
* Stub hash: 28b297e0067c033cea6e2c42fb1f42d4585234ac */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0)
55
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "null")
@@ -72,7 +72,7 @@ ZEND_END_ARG_INFO()
7272

7373
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_blPop, 0, 2, IS_ARRAY, 0)
7474
ZEND_ARG_TYPE_MASK(0, key, MAY_BE_STRING|MAY_BE_ARRAY, NULL)
75-
ZEND_ARG_TYPE_MASK(0, timeout_or_key, MAY_BE_STRING|MAY_BE_LONG, NULL)
75+
ZEND_ARG_OBJ_TYPE_MASK(0, timeout_or_key, double, MAY_BE_STRING|MAY_BE_LONG, NULL)
7676
ZEND_ARG_VARIADIC_TYPE_INFO(0, extra_args, IS_MIXED, 0)
7777
ZEND_END_ARG_INFO()
7878

@@ -84,9 +84,13 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_brpoplpush, 0, 3, IS
8484
ZEND_ARG_TYPE_INFO(0, timeout, IS_LONG, 0)
8585
ZEND_END_ARG_INFO()
8686

87-
#define arginfo_class_Redis_bzPopMax arginfo_class_Redis_blPop
87+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_bzPopMax, 0, 2, IS_ARRAY, 0)
88+
ZEND_ARG_TYPE_MASK(0, key, MAY_BE_STRING|MAY_BE_ARRAY, NULL)
89+
ZEND_ARG_TYPE_MASK(0, timeout_or_key, MAY_BE_STRING|MAY_BE_LONG, NULL)
90+
ZEND_ARG_VARIADIC_TYPE_INFO(0, extra_args, IS_MIXED, 0)
91+
ZEND_END_ARG_INFO()
8892

89-
#define arginfo_class_Redis_bzPopMin arginfo_class_Redis_blPop
93+
#define arginfo_class_Redis_bzPopMin arginfo_class_Redis_bzPopMax
9094

9195
#define arginfo_class_Redis_clearLastError arginfo_class_Redis_bgSave
9296

redis_commands.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,14 +1461,13 @@ static int gen_varkey_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
14611461
char *kw, int kw_len, int min_argc, int has_timeout,
14621462
char **cmd, int *cmd_len, short *slot)
14631463
{
1464-
zval *z_args, *z_ele;
1464+
zval *z_args, *z_ele, ztimeout = {0};
14651465
HashTable *ht_arr;
14661466
char *key;
14671467
int key_free, i, tail;
14681468
size_t key_len;
14691469
int single_array = 0, argc = ZEND_NUM_ARGS();
14701470
smart_string cmdstr = {0};
1471-
long timeout = 0;
14721471
short kslot = -1;
14731472
zend_string *zstr;
14741473

@@ -1489,8 +1488,9 @@ static int gen_varkey_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
14891488
single_array = argc==1 && Z_TYPE(z_args[0]) == IS_ARRAY;
14901489
} else {
14911490
single_array = argc==2 && Z_TYPE(z_args[0]) == IS_ARRAY &&
1492-
Z_TYPE(z_args[1]) == IS_LONG;
1493-
timeout = Z_LVAL(z_args[1]);
1491+
(Z_TYPE(z_args[1]) == IS_LONG || Z_TYPE(z_args[1]) == IS_DOUBLE);
1492+
if (single_array)
1493+
ZVAL_COPY_VALUE(&ztimeout, &z_args[1]);
14941494
}
14951495

14961496
// If we're running a single array, rework args
@@ -1533,17 +1533,22 @@ static int gen_varkey_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
15331533
zend_string_release(zstr);
15341534
if (key_free) efree(key);
15351535
} ZEND_HASH_FOREACH_END();
1536-
if (has_timeout) {
1537-
redis_cmd_append_sstr_long(&cmdstr, timeout);
1536+
if (Z_TYPE(ztimeout) == IS_LONG) {
1537+
redis_cmd_append_sstr_long(&cmdstr, Z_LVAL(ztimeout));
1538+
} else if (Z_TYPE(ztimeout) == IS_DOUBLE) {
1539+
redis_cmd_append_sstr_dbl(&cmdstr, Z_DVAL(ztimeout));
15381540
}
15391541
} else {
1540-
if (has_timeout && Z_TYPE(z_args[argc-1])!=IS_LONG) {
1541-
php_error_docref(NULL, E_ERROR,
1542-
"Timeout value must be a LONG");
1543-
efree(z_args);
1544-
return FAILURE;
1542+
if (has_timeout) {
1543+
zend_uchar type = Z_TYPE(z_args[argc - 1]);
1544+
if (type == IS_LONG || type == IS_DOUBLE) {
1545+
ZVAL_COPY_VALUE(&ztimeout, &z_args[argc - 1]);
1546+
} else {
1547+
php_error_docref(NULL, E_ERROR, "Timeout value must be a long or double");
1548+
efree(z_args);
1549+
return FAILURE;
1550+
}
15451551
}
1546-
15471552
tail = has_timeout ? argc-1 : argc;
15481553
for(i = 0; i < tail; i++) {
15491554
zstr = zval_get_string(&z_args[i]);
@@ -1571,7 +1576,10 @@ static int gen_varkey_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
15711576
zend_string_release(zstr);
15721577
if (key_free) efree(key);
15731578
}
1574-
if (has_timeout) {
1579+
1580+
if (Z_TYPE(ztimeout) == IS_DOUBLE) {
1581+
redis_cmd_append_sstr_dbl(&cmdstr, Z_DVAL(z_args[tail]));
1582+
} else if (Z_TYPE(ztimeout) == IS_LONG) {
15751583
redis_cmd_append_sstr_long(&cmdstr, Z_LVAL(z_args[tail]));
15761584
}
15771585

redis_legacy_arginfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 2b1fc18e5c464c551df8572363972769b2ec1096 */
2+
* Stub hash: 28b297e0067c033cea6e2c42fb1f42d4585234ac */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0)
55
ZEND_ARG_INFO(0, options)

tests/RedisTest.php

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -963,18 +963,24 @@ public function testrPop()
963963
}
964964

965965
public function testblockingPop() {
966+
/* Test with a double timeout in Redis >= 6.0.0 */
967+
if (version_compare($this->version, "6.0.0") >= 0) {
968+
$this->redis->del('list');
969+
$this->redis->lpush('list', 'val1', 'val2');
970+
$this->assertEquals(['list', 'val2'], $this->redis->blpop(['list'], .1));
971+
$this->assertEquals(['list', 'val1'], $this->redis->blpop(['list'], .1));
972+
}
973+
966974
// non blocking blPop, brPop
967975
$this->redis->del('list');
968-
$this->redis->lPush('list', 'val1');
969-
$this->redis->lPush('list', 'val2');
970-
$this->assertTrue($this->redis->blPop(['list'], 2) === ['list', 'val2']);
971-
$this->assertTrue($this->redis->blPop(['list'], 2) === ['list', 'val1']);
976+
$this->redis->lPush('list', 'val1', 'val2');
977+
$this->assertEquals(['list', 'val2'], $this->redis->blPop(['list'], 2));
978+
$this->assertEquals(['list', 'val1'], $this->redis->blPop(['list'], 2));
972979

973980
$this->redis->del('list');
974-
$this->redis->lPush('list', 'val1');
975-
$this->redis->lPush('list', 'val2');
976-
$this->assertTrue($this->redis->brPop(['list'], 1) === ['list', 'val1']);
977-
$this->assertTrue($this->redis->brPop(['list'], 1) === ['list', 'val2']);
981+
$this->redis->lPush('list', 'val1', 'val2');
982+
$this->assertEquals(['list', 'val1'], $this->redis->brPop(['list'], 1));
983+
$this->assertEquals(['list', 'val2'], $this->redis->brPop(['list'], 1));
978984

979985
// blocking blpop, brpop
980986
$this->redis->del('list');

0 commit comments

Comments
 (0)