Przeglądaj źródła

New command: BRPOPLPUSH (Redis v2.2-dev).

Daniele Alessandri 14 lat temu
rodzic
commit
35fd6ca509
2 zmienionych plików z 30 dodań i 0 usunięć
  1. 5 0
      lib/Predis.php
  2. 25 0
      test/RedisCommandsTest.php

+ 5 - 0
lib/Predis.php

@@ -1835,6 +1835,7 @@ class RedisServer_vNext extends RedisServer_v2_0 {
             'rpushx'                    => '\Predis\Commands\ListPushTailX',
             'lpushx'                    => '\Predis\Commands\ListPushHeadX',
             'linsert'                   => '\Predis\Commands\ListInsert',
+            'brpoplpush'                => '\Predis\Commands\ListPopLastPushHeadBlocking',
 
             /* commands operating on sorted sets */
             'zrevrangebyscore'          => '\Predis\Commands\ZSetReverseRangeByScore',
@@ -2484,6 +2485,10 @@ class ListPopLastPushHeadBulk extends \Predis\MultiBulkCommand {
     public function getCommandId() { return 'RPOPLPUSH'; }
 }
 
+class ListPopLastPushHeadBlocking extends \Predis\MultiBulkCommand {
+    public function getCommandId() { return 'BRPOPLPUSH'; }
+}
+
 class ListPopFirst extends \Predis\MultiBulkCommand {
     public function getCommandId() { return 'LPOP'; }
 }

+ 25 - 0
test/RedisCommandsTest.php

@@ -810,6 +810,31 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
         $this->assertEquals((float)(time() - $start), 2, '', 1);
     }
 
+    function testListBlockingPopLastPushHead() {
+        // TODO: this test does not cover all the aspects of BLPOP/BRPOP as it
+        //       does not run with a concurrent client pushing items on lists.
+        $numbers = RC::pushTailAndReturn($this->redis, 'numbers', array(1, 2, 3));
+        $src_count = count($numbers);
+        $dst_count = 0;
+
+        while ($item = $this->redis->brpoplpush('numbers', 'temporary', 1)) {
+            $this->assertEquals(--$src_count, $this->redis->llen('numbers'));
+            $this->assertEquals(++$dst_count, $this->redis->llen('temporary'));
+            $this->assertEquals(array_pop($numbers), $this->redis->lindex('temporary', 0));
+        }
+
+        $start = time();
+        $this->assertNull($this->redis->brpoplpush('numbers', 'temporary', 2));
+        $this->assertEquals(2, (float)(time() - $start), '', 1);
+
+        RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
+            $test->redis->del('numbers');
+            $test->redis->del('temporary');
+            $test->redis->set('numbers', 'foobar');
+            $test->redis->brpoplpush('numbers', 'temporary', 1);
+        });
+    }
+
     function testListInsert() {
         $numbers = RC::pushTailAndReturn($this->redis, 'numbers', RC::getArrayOfNumbers());