</pre><h2><aname="Design pattern: Implementing locking with SETNX">Design pattern: Implementing locking with SETNX</a></h2><blockquote>SETNX can also be seen as a locking primitive. For instance to acquirethe lock of the key <b>foo</b>, the client could try the following:</blockquote>
<preclass="codeblock python python"name="code">
SETNX lock.foo <current UNIX time + lock timeout + 1>
</pre><blockquote>If SETNX returns 1 the client acquired the lock, setting the <b>lock.foo</b>key to the UNIX time at witch the lock should no longer be considered valid.The client will later use <b>DEL lock.foo</b> in order to release the lock.</blockquote>
<blockquote>If SETNX returns 0 the key is already locked by some other client. We caneither return to the caller if it's a non blocking lock, or enter aloop retrying to hold the lock until we succeed or some kind of timeoutexpires.</blockquote>
<h3><aname="Handling deadlocks">Handling deadlocks</a></h3><blockquote>In the above locking algorithm there is a problem: what happens if a clientfails, crashes, or is otherwise not able to release the lock?It's possible to detect this condition because the lock key contains aUNIX timestamp. If such a timestamp is <= the current Unix time the lockis no longer valid.</blockquote>
<blockquote>When this happens we can't just call DEL against the key to remove the lockand then try to issue a SETNX, as there is a race condition here, whenmultiple clients detected an expired lock and are trying to release it.</blockquote>
<ul><li> C1 and C2 read lock.foo to check the timestamp, because SETNX returned 0 to both C1 and C2, as the lock is still hold by C3 that crashed after holding the lock.</li><li> C1 sends DEL lock.foo</li><li> C1 sends SETNX => success!</li><li> C2 sends DEL lock.foo</li><li> C2 sends SETNX => success!</li><li> ERROR: both C1 and C2 acquired the lock because of the race condition.</li></ul>
<blockquote>Fortunately it's possible to avoid this issue using the following algorithm.Let's see how C4, our sane client, uses the good algorithm:</blockquote>
<ul><li> C4 sends SETNX lock.foo in order to acquire the lock</li><li> The crashed C3 client still holds it, so Redis will reply with 0 to C4.</li><li> C4 GET lock.foo to check if the lock expired. If not it will sleep one second (for instance) and retry from the start.</li><li> If instead the lock is expired because the UNIX time at lock.foo is older than the current UNIX time, C4 tries to perform GETSET lock.foo <current unix timestamp + lock timeout + 1></li><li> Thanks to the <ahref="GetsetCommand.html">GETSET</a> command semantic C4 can check if the old value stored at key is still an expired timestamp. If so we acquired the lock!</li><li> Otherwise if another client, for instance C5, was faster than C4 and acquired the lock with the GETSET operation, C4 GETSET operation will return a non expired timestamp. C4 will simply restart from the first step. Note that even if C4 set the key a bit a few seconds in the future this is not a problem.</li></ul>
<b>SortCommand: Contents</b><br> <ahref="#Sorting by external keys">Sorting by external keys</a><br> <ahref="#Retrieving external keys">Retrieving external keys</a><br> <ahref="#Storing the result of a SORT operation">Storing the result of a SORT operation</a><br> <ahref="#Return value">Return value</a>
<blockquote>Sort the elements contained in the List or Set value at <i>key</i>. By defaultsorting is numeric with elements being compared as double precisionfloating point numbers. This is the simplest form of SORT.</blockquote>
<blockquote>Sort the elements contained in the <ahref="Lists.html">List</a>, <ahref="Sets.html">Set</a>, or<ahref="SortedSets.html">Sorted Set</a> value at <i>key</i>. By defaultsorting is numeric with elements being compared as double precisionfloating point numbers. This is the simplest form of SORT:</blockquote>
<preclass="codeblock python"name="code">
<preclass="codeblock python"name="code">
SORT mylist
SORT mylist
</pre><blockquote>Assuming mylist contains a list of numbers, the return value will bethe list of numbers ordered from the smallest to the bigger number.In order to get the sorting in reverse order use DESC:</blockquote>
</pre><blockquote>Assuming mylist contains a list of numbers, the return value will bethe list of numbers ordered from the smallest to the biggest number.In order to get the sorting in reverse order use <b>DESC</b>:</blockquote>
<preclass="codeblock python python"name="code">
<preclass="codeblock python python"name="code">
SORT mylist DESC
SORT mylist DESC
</pre><blockquote>ASC is also supported but it's the default so you don'treally need it.If you want to sort lexicographically use ALPHA. Note that Redis isutf-8 aware assuming you set the right value for the LC_COLLATEenvironment variable.</blockquote>
</pre><blockquote>The <b>ASC</b> option is also supported but it's the default so you don'treally need it.If you want to sort lexicographically use <b>ALPHA</b>. Note that Redis isutf-8 aware assuming you set the right value for the LC_COLLATEenvironment variable.</blockquote>
<blockquote>Sort is able to limit the number of results using the LIMIT option:</blockquote>
<blockquote>Sort is able to limit the number of returned elements using the <b>LIMIT</b> option:</blockquote>
</pre><blockquote>In the above example SORT will return only 10 elements, starting fromthe first one (star is zero-based). Almost all the sort options canbe mixed together. For example:</blockquote>
</pre><blockquote>In the above example SORT will return only 10 elements, starting fromthe first one (start is zero-based). Almost all the sort options canbe mixed together. For example the command:</blockquote>
</pre><blockquote>Will sort <i>mylist</i> lexicographically, in descending order, returning onlythe first 10 elements.</blockquote>
</pre><blockquote>Will sort <i>mylist</i> lexicographically, in descending order, returning onlythe first 10 elements.</blockquote>
<blockquote>Sometimes you want to sort elements using external keys as weights tocompare instead to compare the actual List or Set elements.For examplethe list <i>mylist</i> may contain the elements 1, 2, 3, 4, thatare justthe unique IDs of objects stored at object_1, object_2, object_3and object_4, while the keys weight_1, weight_2, weight_3 and weight_4can contain weights we want to use to sort the list of objectsidentifiers. We can use the following command:</blockquote>
<blockquote>Sometimes you want to sort elements using external keys as weights tocompare instead to compare the actual List Sets or Sorted Set elements.For examplethe list <i>mylist</i> may contain the elements 1, 2, 3, 4, thatare just unique IDs of objects stored at object_1, object_2, object_3and object_4, while the keys weight_1, weight_2, weight_3 and weight_4can contain weights we want to use to sort our list of objectsidentifiers. We can use the following command:</blockquote>
<h2><aname="Sorting by external keys">Sorting by external keys</a></h2><preclass="codeblock python python python python python"name="code">
SORT mylist BY weight_*
SORT mylist BY weight_*
</pre><blockquote>the BY option takes a pattern (<codename="code"class="python">weight_*</code> in our example) that is usedin order to generate the key names of the weights used for sorting.Weight key names are obtained substituting the first occurrence of <codename="code"class="python">*</code>with the actual value of the elements on the list (1,2,3,4 in our example).</blockquote>
</pre><blockquote>the <b>BY</b> option takes a pattern (<codename="code"class="python">weight_*</code> in our example) that is usedin order to generate the key names of the weights used for sorting.Weight key names are obtained substituting the first occurrence of <codename="code"class="python">*</code>with the actual value of the elements on the list (1,2,3,4 in our example).</blockquote>
<blockquote>Still our previous example will return just the sorted IDs. Often it isneeded to get the actual objects sorted (object_1, ..., object_4 in theexample). We can do it with the following command:</blockquote>
<blockquote>Our previous example will return just the sorted IDs. Often it isneeded to get the actual objects sorted (object_1, ..., object_4 in theexample). We can do it with the following command:</blockquote>
</pre><blockquote>Note that GET can be used multiple times in order to get more keys forevery element of the original List or Set sorted.</blockquote>
</pre><blockquote>Note that <b>GET</b> can be used multiple times in order to get more keys forevery element of the original List, Set or Sorted Set sorted.</blockquote>
<blockquote>Since Redis >= 1.1 it's possible to also GET the list elements itselfusing the special # pattern:</blockquote>
<blockquote>Since Redis >= 1.1 it's possible to also GET the list elements itselfusing the special # pattern:</blockquote>
</pre><h2><aname="Return value">Return value</a></h2><ahref="ReplyTypes.html">Multi bulk reply</a>, specifically a list of sorted elements.
</pre><h2><aname="Storing the result of a SORT operation">Storing the result of a SORT operation</a></h2><blockquote>By default SORT returns the sorted elements as its return value.Using the <b>STORE</b> option instead to return the elements SORT willstore this elements as a <ahref="Lists.html">Redis List</a> in the specified key.An example:</blockquote>
</pre><blockquote>An interesting pattern using SORT ... STORE consists in associatingan <ahref="ExpireCommand.html">EXPIRE</a> timeout to the resulting key so that inapplications where the result of a sort operation can be cached forsome time other clients will use the cached list instead to call SORTfor every request. When the key will timeout an updated version ofthe cache can be created using SORT ... STORE again.</blockquote>
<blockquote>Note that implementing this pattern it is important to avoid that multipleclients will try to rebuild the cached version of the cacheat the same time, so some form of locking should be implemented(for instance using <ahref="SetnxCommand.html">SETNX</a>).</blockquote>
<h2><aname="Return value">Return value</a></h2><ahref="ReplyTypes.html">Multi bulk reply</a>, specifically a list of sorted elements.