public virtual PredicateResults GetTheLock(ZooKeeper client, List <string> sortedChildren, string sequenceNodePath, int maxLeases) { var sequenceNodeName = ZKPaths.GetNodeFromPath(sequenceNodePath); var ourIndex = sortedChildren.IndexOf(sequenceNodeName); if (ourIndex < 0) { throw new KeeperException.NoNodeException(sequenceNodePath); } var locked = ourIndex < maxLeases; var nodeToWatch = locked ? null : sortedChildren[ourIndex - maxLeases]; return(new PredicateResults(nodeToWatch, locked)); }
private PredicateResults ReadLockPredicate(List <string> children, string sequenceNodePath) { // 已获取写锁可以直接获取读锁 if (_writeLock.IsAcquiredLock()) { return(new PredicateResults(null, true)); } int watchWriteIndex = int.MaxValue; int ourIndex = -1; var sequenceNodeName = ZKPaths.GetNodeFromPath(sequenceNodePath); for (int index = 0; index < children.Count; index++) { var node = children[index]; // 写锁节点 if (node.Contains(ZookeeperReadWriteLock.WRITE_LOCK_NAME)) { watchWriteIndex = index; } // 当前读锁节点 else if (node == sequenceNodeName) { ourIndex = index; break; } } if (ourIndex < 0) { throw new KeeperException.NoNodeException(sequenceNodePath); } var locked = (ourIndex < watchWriteIndex); var pathToWatch = locked ? null : children[watchWriteIndex]; return(new PredicateResults(pathToWatch, locked)); }
/// <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); }