|
@@ -0,0 +1,41 @@
|
|
|
+<?php
|
|
|
+require_once 'SharedConfigurations.php';
|
|
|
+
|
|
|
+/*
|
|
|
+This is an implementation of an atomic client-side ZPOP using the support for
|
|
|
+check-and-set (CAS) operations with MULTI/EXEC transactions, as described in
|
|
|
+"WATCH explained" from http://redis.io/topics/transactions
|
|
|
+
|
|
|
+First, populate your database with a tiny sample data set:
|
|
|
+
|
|
|
+./redis-cli
|
|
|
+SELECT 15
|
|
|
+ZADD zset 1 a
|
|
|
+ZADD zset 2 b
|
|
|
+ZADD zset 3 c
|
|
|
+*/
|
|
|
+
|
|
|
+function zpop($client, $zsetKey) {
|
|
|
+ $element = null;
|
|
|
+ $options = array(
|
|
|
+ 'cas' => true, // Initialize with support for CAS operations
|
|
|
+ 'watch' => $zsetKey, // Key that needs to be WATCHed to detect changes
|
|
|
+ 'retry' => 3, // Number of retries on aborted transactions, after
|
|
|
+ // which the client bails out with an exception.
|
|
|
+ );
|
|
|
+
|
|
|
+ $txReply = $client->multiExec($options, function($tx)
|
|
|
+ use ($zsetKey, &$element) {
|
|
|
+ @list($element) = $tx->zrange($zsetKey, 0, 0);
|
|
|
+ if (isset($element)) {
|
|
|
+ $tx->multi(); // With CAS, MULTI *must* be explicitly invoked.
|
|
|
+ $tx->zrem($zsetKey, $element);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return $element;
|
|
|
+}
|
|
|
+
|
|
|
+$redis = new Predis\Client($single_server, 'dev');
|
|
|
+$zpopped = zpop($redis, 'zset');
|
|
|
+echo isset($zpopped) ? "ZPOPed $zpopped" : "Nothing to ZPOP!", "\n";
|
|
|
+?>
|