public IDistributedReadWriteLock CreateReadWriteLock(string name) { var path = ZKPaths.MakePath(BASE_LOCK_PATH, name); var rwlock = new ZookeeperReadWriteLock(_zkClient, path, _options.DefaultLockTimeout); return(rwlock); }
//public ZookeeperLockProvider(ZooKeeper zkClient) //{ // _zkClient = zkClient; //} //public ZookeeperLockProvider(string connectString, int sessionTimeout) //{ // _zkClient = new ZooKeeper(connectString, sessionTimeout, null); //} public IDistributedLock CreateMutexLock(string name) { var path = ZKPaths.MakePath(BASE_LOCK_PATH, name); var mlock = new ZookeeperMutexLock(_zkClient, path, _options.DefaultLockTimeout); return(mlock); }
public LockInternals(ZooKeeper zkClient, ILockInternalsDriver driver, string path, string lockName, int maxLeases) { _driver = driver; _lockName = lockName; _maxLeases = maxLeases; _zkClient = zkClient; _basePath = ZKPaths.ValidatePath(path); _path = ZKPaths.MakePath(path, lockName); _signal = new SemaphoreSlim(0); _watcher = new ReleaseLockWatcher(_signal); }
/// <summary> /// zk信号量 /// </summary> /// <param name="zkClient"></param> /// <param name="path"></param> /// <param name="maxLeases"></param> public ZookeeperSemaphore(ZooKeeper zkClient, string path, int maxLeases, int lockTimeout) { ZKPaths.ValidatePath(path); _zkClient = zkClient; _maxLeases = maxLeases; _lockTimeout = lockTimeout; _lock = new ZookeeperMutexLock(zkClient, ZKPaths.MakePath(path, LOCK_PARENT), lockTimeout); _leasesPath = ZKPaths.MakePath(path, LEASE_PARENT); _acquiredLeases = new List <string>(maxLeases); _signal = new SemaphoreSlim(0); _watcher = new ReleaseLockWatcher(_signal); }
/// <summary> /// 获取一个Lease /// </summary> /// <param name="startMs">开始毫秒数</param> /// <param name="waitMs">等待毫秒数</param> /// <returns>Lease节点名称</returns> private async Task <string> InternalAcquireOneLeaseAsync(long startMs, long waitMs) { // 获取剩余等待时间 var remainingTime = GetRemainingWaitMs(startMs, waitMs); if (remainingTime <= 0) { new TimeoutException("等待超时"); } // 获取分布式锁 await _lock.AcquireAsync(remainingTime); string leasePath; var success = false; try { // 创建Lease临时有序节点 leasePath = await _zkClient.createAsync(ZKPaths.MakePath(_leasesPath, LEASE_BASE_NAME), null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); // 节点名称 var leaseNodeName = ZKPaths.GetNodeFromPath(leasePath); try { while (true) { var childrenResult = await _zkClient.getChildrenAsync(_leasesPath, _watcher); // 找不到刚创建的Lease节点 if (!childrenResult.Children.Contains(leaseNodeName)) { throw new KeeperException.NoNodeException("Sequential path not found - possible session loss"); } // 成功获取一个Lease if (childrenResult.Children.Count <= _maxLeases) { break; } // 剩余等待时间 remainingTime = GetRemainingWaitMs(startMs, waitMs); if (remainingTime <= 0) { throw new TimeoutException("等待超时"); } // 等待被唤醒 var result = await _signal.WaitAsync(remainingTime); if (!result) { throw new TimeoutException("等待超时"); } } success = true; } finally { if (!success) { await DeleteLease(leasePath); } } } finally { await _lock.ReleaseAsync(); } return(leasePath); }
private async Task <bool> InternalLockLoopAsync(long startMillis, int millisToWait, string ourPath) { var haveTheLock = false; var doDelete = false; try { while (_zkClient.getState() == ZooKeeper.States.CONNECTED) { // 获取排序的子节点 var children = await GetSortedChildren(); //var sequenceNodeName = ourPath.Substring(_basePath.Length + 1); // 判断能否持有锁 var predicateResults = _driver.GetTheLock(_zkClient, children, ourPath, _maxLeases); // 已获取到锁 if (predicateResults.Locked) { return(true); } // 上一个节点路径 var previousSequencePath = ZKPaths.MakePath(_basePath, predicateResults.NodeToWatch); try { // 剩余等待时间 millisToWait -= (int)(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - startMillis); startMillis = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); if (millisToWait <= 0) { // 超时,删除创建的节点 doDelete = true; break; } // 设置释放锁监听 await _zkClient.getDataAsync(previousSequencePath, _watcher); // 阻塞 等待锁释放或超时 if (!await _signal.WaitAsync(millisToWait)) { doDelete = true; break; } } catch (KeeperException.NoNodeException ex) { // 上一个节点已被删除(即释放锁)。再次尝试获取 } } } catch (Exception ex) { doDelete = true; throw ex; } finally { if (doDelete) { await DeleteOurPathAsync(ourPath); } } return(haveTheLock); }