public bool Lock(RedisKey resource, TimeSpan ttl, out Lock lockObject) { var val = CreateUniqueLockId(); Lock innerLock = null; bool successfull = retry(DefaultRetryCount, DefaultRetryDelay, () => { try { int n = 0; var startTime = DateTime.Now; // Use keys for_each_redis_registered( redis => { if (LockInstance(redis, resource, val, ttl)) n += 1; } ); /* * Add 2 milliseconds to the drift to account for Redis expires * precision, which is 1 milliescond, plus 1 millisecond min drift * for small TTLs. */ var drift = Convert.ToInt32((ttl.TotalMilliseconds * ClockDriveFactor) + 2); var validity_time = ttl - (DateTime.Now - startTime) - new TimeSpan(0, 0, 0, 0, drift); if (n >= Quorum && validity_time.TotalMilliseconds > 0) { innerLock = new Lock(resource, val, validity_time); return true; } else { for_each_redis_registered( redis => { UnlockInstance(redis, resource, val); } ); return false; } } catch (Exception) { return false; } }); lockObject = innerLock; return successfull; }
public void Unlock(Lock lockObject) { for_each_redis_registered(redis => { UnlockInstance(redis, lockObject.Resource, lockObject.Value); }); }