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

Skip to content

Commit 43da8dd

Browse files
Refactor BRPOPLPUSH and add B[LR]POP documentation
1 parent 375d093 commit 43da8dd

8 files changed

Lines changed: 106 additions & 51 deletions

redis.stub.php

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ public function bgrewriteaof(): Redis|bool;
161161
/**
162162
* Count the number of set bits in a Redis string.
163163
*
164-
* @see https://https://redis.io/commands/bitcount/
164+
* @see https://redis.io/commands/bitcount/
165165
*
166166
* @param string $key The key in question (must be a string key)
167167
* @param int $start The index where Redis should start counting. If ommitted it
@@ -182,7 +182,7 @@ public function bitop(string $operation, string $deskey, string $srckey, string
182182
/**
183183
* Return the position of the first bit set to 0 or 1 in a string.
184184
*
185-
* @see https://https://redis.io/commands/bitpos/
185+
* @see https://redis.io/commands/bitpos/
186186
*
187187
* @param string $key The key to check (must be a string)
188188
* @param bool $bit Whether to look for an unset (0) or set (1) bit.
@@ -195,11 +195,54 @@ public function bitop(string $operation, string $deskey, string $srckey, string
195195
**/
196196
public function bitpos(string $key, bool $bit, int $start = 0, int $end = -1, bool $bybit = false): Redis|int|false;
197197

198-
public function blPop(string|array $key, string|float|int $timeout_or_key, mixed ...$extra_args): Redis|array|null|false;
198+
/**
199+
* Pop an element off the beginning of a Redis list or lists, potentially blocking up to a specified
200+
* timeout. This method may be called in two distinct ways, of which examples are provided below.
201+
*
202+
* @see https://redis.io/commands/blpop/
203+
*
204+
* @param string|array $key_or_keys This can either be a string key or an array of one or more
205+
* keys.
206+
* @param string|float|int $timeout_or_key If the previous argument was a string key, this can either
207+
* be an additional key, or the timeout you wish to send to
208+
* the command.
209+
*
210+
* <code>
211+
* <?php>
212+
* // One way to call this method is in a variadic way, with the final argument being
213+
* // the intended timeout.
214+
* $redis->blPop('list1', 'list2', 'list3', 1.5);
215+
*
216+
* // Alternatively, you can send an array of keys
217+
* $relay->blPop(['list1', 'list2', 'list3'], 1.5);
218+
* ?>
219+
* </code>
220+
*/
221+
public function blPop(string|array $key_or_keys, string|float|int $timeout_or_key, mixed ...$extra_args): Redis|array|null|false;
199222

200-
public function brPop(string|array $key, string|float|int $timeout_or_key, mixed ...$extra_args): Redis|array|null|false;
223+
/**
224+
* Pop an element off of the end of a Redis list or lists, potentially blocking up to a specified timeout.
225+
* The calling convention is identical to Redis::blPop() so see that documentation for more details.
226+
*
227+
* @see https://redis.io/commands/brpop/
228+
* @see Redis::blPop()
229+
*
230+
*/
231+
public function brPop(string|array $key_or_keys, string|float|int $timeout_or_key, mixed ...$extra_args): Redis|array|null|false;
201232

202-
public function brpoplpush(string $src, string $dst, int $timeout): Redis|string|false;
233+
/**
234+
* Pop an element from the end of a Redis list, pushing it to the beginning of another Redis list,
235+
* optionally blocking up to a specified timeout.
236+
*
237+
* @see https://redis.io/commands/brpoplpush/
238+
*
239+
* @param string $src The source list
240+
* @param string $dst The destination list
241+
* @param int|float $timeout The number of seconds to wait. Note that you must be connected
242+
* to Redis >= 6.0.0 to send a floating point timeout.
243+
*
244+
*/
245+
public function brpoplpush(string $src, string $dst, int|float $timeout): Redis|string|false;
203246

204247
public function bzPopMax(string|array $key, string|int $timeout_or_key, mixed ...$extra_args): Redis|array|false;
205248

@@ -755,7 +798,7 @@ public function slowlog(string $operation, int $length = 0): mixed;
755798
/**
756799
* Sort the contents of a Redis key in various ways.
757800
*
758-
* @see https://https://redis.io/commands/sort/
801+
* @see https://redis.io/commands/sort/
759802
*
760803
* @param string $key The key you wish to sort
761804
* @param array $options Various options controlling how you would like the
@@ -933,7 +976,7 @@ public function zPopMin(string $key, int $value = null): Redis|array|false;
933976
* How the command works in particular is greatly affected by the options that
934977
* are passed in.
935978
*
936-
* @see https://https://redis.io/commands/zrange/
979+
* @see https://redis.io/commands/zrange/
937980
* @category zset
938981
*
939982
* @param string $key The sorted set in question.
@@ -973,7 +1016,7 @@ public function zRangeByScore(string $key, string $start, string $end, array $op
9731016
* This command is similar to ZRANGE except that instead of returning the values directly
9741017
* it will store them in a destination key provided by the user
9751018
*
976-
* @see https://https://redis.io/commands/zrange/
1019+
* @see https://redis.io/commands/zrange/
9771020
* @see Redis::zRange
9781021
* @category zset
9791022
*

redis_arginfo.h

Lines changed: 3 additions & 3 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: 21ca57fa960dd8afd88a830b1628e229e831476d */
2+
* Stub hash: b42e3cb1c1b50ae6cac12314b83116657365c7c4 */
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_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_bitpos, 0, 2, Re
7272
ZEND_END_ARG_INFO()
7373

7474
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_blPop, 0, 2, Redis, MAY_BE_ARRAY|MAY_BE_NULL|MAY_BE_FALSE)
75-
ZEND_ARG_TYPE_MASK(0, key, MAY_BE_STRING|MAY_BE_ARRAY, NULL)
75+
ZEND_ARG_TYPE_MASK(0, key_or_keys, MAY_BE_STRING|MAY_BE_ARRAY, NULL)
7676
ZEND_ARG_TYPE_MASK(0, timeout_or_key, MAY_BE_STRING|MAY_BE_DOUBLE|MAY_BE_LONG, NULL)
7777
ZEND_ARG_VARIADIC_TYPE_INFO(0, extra_args, IS_MIXED, 0)
7878
ZEND_END_ARG_INFO()
@@ -82,7 +82,7 @@ ZEND_END_ARG_INFO()
8282
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_brpoplpush, 0, 3, Redis, MAY_BE_STRING|MAY_BE_FALSE)
8383
ZEND_ARG_TYPE_INFO(0, src, IS_STRING, 0)
8484
ZEND_ARG_TYPE_INFO(0, dst, IS_STRING, 0)
85-
ZEND_ARG_TYPE_INFO(0, timeout, IS_LONG, 0)
85+
ZEND_ARG_TYPE_MASK(0, timeout, MAY_BE_LONG|MAY_BE_DOUBLE, NULL)
8686
ZEND_END_ARG_INFO()
8787

8888
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_bzPopMax, 0, 2, Redis, MAY_BE_ARRAY|MAY_BE_FALSE)

redis_cluster.stub.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,19 @@ public function bitop(string $operation, string $deskey, string $srckey, string
7575
*/
7676
public function bitpos(string $key, bool $bit, int $start = 0, int $end = -1, bool $bybit = false): RedisCluster|int|false;
7777

78+
/**
79+
* See Redis::blpop()
80+
*/
7881
public function blpop(string|array $key, string|float|int $timeout_or_key, mixed ...$extra_args): RedisCluster|array|null|false;
82+
83+
/**
84+
* See Redis::brpop()
85+
*/
7986
public function brpop(string|array $key, string|float|int $timeout_or_key, mixed ...$extra_args): RedisCluster|array|null|false;
8087

88+
/**
89+
* See Redis::brpoplpush()
90+
*/
8191
public function brpoplpush(string $srckey, string $deskey, int $timeout): mixed;
8292

8393
public function bzpopmax(string|array $key, string|int $timeout_or_key, mixed ...$extra_args): array;

redis_cluster_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: aed47186facc916ab9732d986c0fde1b86e2dede */
2+
* Stub hash: 3d725e57f5f42243985bca2e64cf727b2475c644 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1)
55
ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 1)

redis_cluster_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: aed47186facc916ab9732d986c0fde1b86e2dede */
2+
* Stub hash: 3d725e57f5f42243985bca2e64cf727b2475c644 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1)
55
ZEND_ARG_INFO(0, name)

redis_commands.c

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2201,49 +2201,37 @@ redis_getex_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
22012201
int redis_brpoplpush_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
22022202
char **cmd, int *cmd_len, short *slot, void **ctx)
22032203
{
2204-
char *key1, *key2;
2205-
size_t key1_len, key2_len;
2206-
int key1_free, key2_free;
2207-
short slot1, slot2;
2208-
zend_long timeout;
2209-
2210-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssl", &key1, &key1_len,
2211-
&key2, &key2_len, &timeout) == FAILURE)
2212-
{
2213-
return FAILURE;
2214-
}
2204+
zend_string *src = NULL, *dst = NULL;
2205+
double timeout = 0;
22152206

2216-
// Key prefixing
2217-
key1_free = redis_key_prefix(redis_sock, &key1, &key1_len);
2218-
key2_free = redis_key_prefix(redis_sock, &key2, &key2_len);
2207+
ZEND_PARSE_PARAMETERS_START(3, 3)
2208+
Z_PARAM_STR(src)
2209+
Z_PARAM_STR(dst)
2210+
Z_PARAM_DOUBLE(timeout)
2211+
ZEND_PARSE_PARAMETERS_END_EX(return FAILURE);
22192212

2220-
// In cluster mode, verify the slots match
2221-
if (slot) {
2222-
slot1 = cluster_hash_key(key1, key1_len);
2223-
slot2 = cluster_hash_key(key2, key2_len);
2224-
if (slot1 != slot2) {
2225-
php_error_docref(NULL, E_WARNING,
2226-
"Keys hash to different slots!");
2227-
if (key1_free) efree(key1);
2228-
if (key2_free) efree(key2);
2229-
return FAILURE;
2230-
}
2213+
src = redis_key_prefix_zstr(redis_sock, src);
2214+
dst = redis_key_prefix_zstr(redis_sock, dst);
22312215

2232-
// Both slots are the same
2233-
*slot = slot1;
2216+
if (slot && (*slot = cluster_hash_key_zstr(src)) != cluster_hash_key_zstr(dst)) {
2217+
php_error_docref(NULL, E_WARNING, "Keys must hash to the same slot");
2218+
zend_string_release(src);
2219+
zend_string_release(dst);
2220+
return FAILURE;
22342221
}
22352222

2236-
// Consistency with Redis, if timeout < 0 use RPOPLPUSH
2223+
/* Consistency with Redis. If timeout < 0 use RPOPLPUSH */
22372224
if (timeout < 0) {
2238-
*cmd_len = REDIS_CMD_SPPRINTF(cmd, "RPOPLPUSH", "ss", key1, key1_len,
2239-
key2, key2_len);
2225+
*cmd_len = REDIS_CMD_SPPRINTF(cmd, "RPOPLPUSH", "SS", src, dst);
2226+
} else if (fabs(timeout - (long)timeout) < .0001) {
2227+
*cmd_len = REDIS_CMD_SPPRINTF(cmd, "BRPOPLPUSH", "SSd", src, dst, (long)timeout);
22402228
} else {
2241-
*cmd_len = REDIS_CMD_SPPRINTF(cmd, "BRPOPLPUSH", "ssd", key1, key1_len,
2242-
key2, key2_len, timeout);
2229+
*cmd_len = REDIS_CMD_SPPRINTF(cmd, "BRPOPLPUSH", "SSf", src, dst, timeout);
22432230
}
22442231

2245-
if (key1_free) efree(key1);
2246-
if (key2_free) efree(key2);
2232+
zend_string_release(src);
2233+
zend_string_release(dst);
2234+
22472235
return SUCCESS;
22482236
}
22492237

redis_legacy_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: 21ca57fa960dd8afd88a830b1628e229e831476d */
2+
* Stub hash: b42e3cb1c1b50ae6cac12314b83116657365c7c4 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0)
55
ZEND_ARG_INFO(0, options)
@@ -67,7 +67,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_bitpos, 0, 0, 2)
6767
ZEND_END_ARG_INFO()
6868

6969
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_blPop, 0, 0, 2)
70-
ZEND_ARG_INFO(0, key)
70+
ZEND_ARG_INFO(0, key_or_keys)
7171
ZEND_ARG_INFO(0, timeout_or_key)
7272
ZEND_ARG_VARIADIC_INFO(0, extra_args)
7373
ZEND_END_ARG_INFO()
@@ -80,9 +80,13 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_brpoplpush, 0, 0, 3)
8080
ZEND_ARG_INFO(0, timeout)
8181
ZEND_END_ARG_INFO()
8282

83-
#define arginfo_class_Redis_bzPopMax arginfo_class_Redis_blPop
83+
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_bzPopMax, 0, 0, 2)
84+
ZEND_ARG_INFO(0, key)
85+
ZEND_ARG_INFO(0, timeout_or_key)
86+
ZEND_ARG_VARIADIC_INFO(0, extra_args)
87+
ZEND_END_ARG_INFO()
8488

85-
#define arginfo_class_Redis_bzPopMin arginfo_class_Redis_blPop
89+
#define arginfo_class_Redis_bzPopMin arginfo_class_Redis_bzPopMax
8690

8791
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_bzmpop, 0, 0, 3)
8892
ZEND_ARG_INFO(0, timeout)

tests/RedisTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2498,6 +2498,7 @@ public function testBRpopLpush() {
24982498
$this->redis->lpush('{list}y', '456'); // y = [456, 123]
24992499

25002500
$this->assertEquals($this->redis->brpoplpush('{list}x', '{list}y', 1), 'abc'); // we RPOP x, yielding abc.
2501+
25012502
$this->assertEquals($this->redis->lrange('{list}x', 0, -1), ['def']); // only def remains in x.
25022503
$this->assertEquals($this->redis->lrange('{list}y', 0, -1), ['abc', '456', '123']); // abc has been lpushed to y.
25032504

@@ -2506,6 +2507,15 @@ public function testBRpopLpush() {
25062507
$this->assertTrue(FALSE === $this->redis->brpoplpush('{list}x', '{list}y', 1));
25072508
$this->assertTrue([] === $this->redis->lrange('{list}x', 0, -1));
25082509
$this->assertTrue([] === $this->redis->lrange('{list}y', 0, -1));
2510+
2511+
if (!$this->minVersionCheck('6.0.0'))
2512+
return;
2513+
2514+
// Redis >= 6.0.0 allows floating point timeouts
2515+
$st = microtime(true);
2516+
$this->assertEquals(FALSE, $this->redis->brpoplpush('{list}x', '{list}y', .1));
2517+
$et = microtime(true);
2518+
$this->assertTrue($et - $st < 1.0);
25092519
}
25102520

25112521
public function testZAddFirstArg() {

0 commit comments

Comments
 (0)