| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [View Raw Code] [Original HTTPS Page] |
The DistributedLock.Redis package offers distributed synchronization primitives based on Redis. For example:
var connection = await ConnectionMultiplexer.ConnectAsync(connectionString); // uses StackExchange.Redis
var @lock = new RedisDistributedLock("MyLockName", connection.GetDatabase());
await using (var handle = await @lock.TryAcquireAsync())
{
if (handle != null) { /* I have the lock */ }
}The RedisDistributedLock and RedisDistributedReaderWriterLock classes implement the RedLock algorithm. This allows you to increase the robustness of those locks by constructing the lock with a set of databases instead of just a single database. The lock is only considered aquired if it is successfully acquired on more than half of the databases.
The RedisDistributedSemaphore implementation is loosely based on this algorithm. Note that RedisDistributedSemaphore does not support multiple databases, because the RedLock algorithm does not work with semaphores.1 When calling CreateSemaphore() on a RedisDistributedSynchronizationProvider that has been constructed with multiple databases, the first database in the list will be used.
Both RedLock and the semaphore algorithm mentioned above claim locks for only a specified period of time. While DistributedLock does this under the hood, it also periodically extends its hold behind the scenes to ensure that the object is not released until the handle returned by Acquire is disposed.
Some Redis synchronization primitives take in a string name as their name and others take in a RedisKey key. In the former case, one or more Redis keys will be created on the database with name as a prefix. In the latter case, the exact key will be used. Make sure your names/keys don't collide with Redis keys you're using for other purposes!
Because of how Redis locks work, the acquire operation cannot truly block. If waiting to acquire a lock or other primitive that is not available, the implementation will periodically sleep and retry until the lease can be taken or the acquire timeout elapses. Because of this, these classes are maximally efficient when using TryAcquire semantics with a timeout of zero.
As of 1.0.1, Redis-based primitives support the use of IDatabase.WithKeyPrefix(keyPrefix) for key space isolation. In such cases all underlying keys will implicitly include the key prefix. Therefore, two locks with the same name targeting the same underlying Redis instance but with different prefixes will not see each other.
In addition to specifying the name/key and database(s), some additional tuning options are available.
1 The reason RedLock does not work with semaphores is that entering a semaphore on a majority of databases does not guarantee that the semaphore's invariant is preserved. For example, imagine a two-count semaphore with three databases (1, 2, and 3) and three users (A, B, and C). We could find ourselves in the following situation: on database 1, users A and B have entered. On database 2, users B and C have entered. On database 3, users A and C have entered. Here all users believe they have entered the semaphore because they've succeeded on two out of three databases.
| Back | FazBrowse Home | New Git URL |