Commit b050439c authored by Marc Gravell's avatar Marc Gravell

Prevent writer getting to the back of the Monitor queue; show EVAL example in...

Prevent writer getting to the back of the Monitor queue; show EVAL example in transactions documentation
parent 81b09e21
...@@ -40,8 +40,8 @@ If, when you check the data, you discover that you don't actually need the trans ...@@ -40,8 +40,8 @@ If, when you check the data, you discover that you don't actually need the trans
forget all the watched keys. Note that watched keys are also reset during `EXEC` and `DISCARD`. So *at the Redis layer*, this is conceptually: forget all the watched keys. Note that watched keys are also reset during `EXEC` and `DISCARD`. So *at the Redis layer*, this is conceptually:
WATCH {custKey} WATCH {custKey}
HGET {custKey} "UniqueId" HEXISTS {custKey} "UniqueId"
(check the value etc, then either:) (check the reply, then either:)
MULTI MULTI
HSET {custKey} "UniqueId" {newId} HSET {custKey} "UniqueId" {newId}
EXEC EXEC
...@@ -90,5 +90,14 @@ atomic commands exist. These are accessed via the `When` parameter - so our prev ...@@ -90,5 +90,14 @@ atomic commands exist. These are accessed via the `When` parameter - so our prev
Lua Lua
--- ---
You should also keep in mind that Lua scripting is a versatile tool for performing multiple operations as a single atomic unit at the server; since no other connections You should also keep in mind that Redis 2.6 and above [support Lua scripting](http://redis.io/commands/EVAL), a versatile tool for performing multiple operations as a single atomic unit at the server.
are serviced during a Lua script it behaves much like a transaction, but without the complexity of `MULTI` / `EXEC` etc. Since no other connections are serviced during a Lua script it behaves much like a transaction, but without the complexity of `MULTI` / `EXEC` etc. This also avoids issues such as bandwidth and latency
between the caller and the server, but the trade-off is that it monopolises the server for the duration of the script.
At the Redis layer (and assuming `HSETNX` did not exist) this could be implemented as:
EVAL "if redis.call('hexists', KEYS[1], 'UniqueId') then return redis.call('hset', KEYS[1], 'UniqueId', ARGV[1]) else return 0 end" 1 {custKey} {newId}
This scrip
Lua scripting is not currently implemented in StackExchange.Redis, but will be very soon.
\ No newline at end of file
...@@ -343,7 +343,9 @@ private enum CallbackOperation ...@@ -343,7 +343,9 @@ private enum CallbackOperation
public void Dispose() public void Dispose()
{ {
lock (writeQueue) lock (writeQueue)
{ // make sure writer threads know to exit {
// make sure writer threads know to exit
isDisposed = true;
Monitor.PulseAll(writeQueue); Monitor.PulseAll(writeQueue);
} }
lock (socketLookup) lock (socketLookup)
...@@ -376,8 +378,9 @@ private void WriteAllQueues() ...@@ -376,8 +378,9 @@ private void WriteAllQueues()
if (writeQueue.Count == 0) if (writeQueue.Count == 0)
{ {
if (isDisposed) break; // <========= exit point if (isDisposed) break; // <========= exit point
Monitor.Wait(writeQueue, 500); Monitor.Wait(writeQueue);
continue; if (isDisposed) break; // (woken by Dispose)
if (writeQueue.Count == 0) continue; // still nothing...
} }
bridge = writeQueue.Dequeue(); bridge = writeQueue.Dequeue();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment