/// <summary> /// 创建Leader选举对象 /// </summary> /// <param name="id">每个Leader选举的参与者都有一个ID标识,用于区分各个参与者。</param> /// <param name="autoRequue">是否在由于网络问题造成与服务器断开连接后,自动参与到选举队列中。</param> /// <param name="delayTimeMillis">延迟选举的时间,主要是针对网络闪断的情况,给Leader以重连并继续成为Leader的机会,一般5秒合适。</param> /// <param name="client">ZKClient</param> /// <param name="leaderPath">选举的路径</param> /// <param name="listener">成为Leader后执行的的监听器</param> public ZKLeaderDelySelector(string id, bool autoRequue, int delayTimeMillis, ZKClient client, string leaderPath, ZKLeaderSelectorListener listener) { this.delayTimeMillis = delayTimeMillis; this.id = id; this.client = client; this.autoRequeue = autoRequue; this.leaderPath = leaderPath; this._lock = ZKDistributedDelayLock.NewInstance(client, leaderPath); this._lock.SetLockNodeData(this.id); this.listener = listener; SetFactory(); stateListener = new ZKStateListener().StateChanged( (state) => { if (state == KeeperState.SyncConnected) { //如果重新连接 if (!isInterrupted) { Requeue(); } } }); }
private ZKHALock(ZKClient client, string lockPach) { this.client = client; this.lockPath = lockPach; countListener = new ZKChildListener().ChildChange( (parentPath, currentChilds) => { if (Check(currentSeq, currentChilds)) { semaphore.Release(); } }); stateListener = new ZKStateListener().StateChanged( (state) => { if (state == KeeperState.SyncConnected) { //如果重新连接 //如果重连后之前的节点已删除,并且lock处于等待状态,则重新创建节点,等待获得lock if (!client.Exists(lockPach + "/" + currentSeq) && !semaphore.WaitOne(1000)) { string newPath = client.Create(lockPath + "/1", null, CreateMode.EphemeralSequential); string[] paths = newPath.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries); currentSeq = paths[paths.Length - 1]; } } }); }
/// <summary> /// 创建Leader选举对象 /// </summary> /// <param name="id"> 每个Leader选举的参与者都有一个ID标识,用于区分各个参与者。</param> /// <param name="autoRequeue"> 是否在由于网络问题造成与服务器断开连接后,自动参与到选举队列中。</param> /// <param name="client"> ZooKeeperClient</param> /// <param name="leaderPath"> 选举的路径</param> /// <param name="listener"> 成为Leader后执行的的监听器</param> public ZKLeaderSelector(string id, bool autoRequeue, ZKClient zkClient, string leaderPath, IZKLeaderSelectorListener listener) { this.id = id; this._zkClient = zkClient; this.autoRequeue = autoRequeue; this.leaderPath = leaderPath; this._lock = new ZKDistributedLock(_zkClient, leaderPath); this._lock.lockNodeData = id; this.listener = listener; this.cancellationTokenSource = new CancellationTokenSource(); this.stateListener = new ZKStateListener(); stateListener.StateChangedHandler = async(state) => { if (state == KeeperState.SyncConnected) { //如果重新连接 if (!isInterrupted) { await Task.Run(() => Requeue()); } } }; }
public void UnSubscribeStateChanges(IZKStateListener stateListener) { _stateListeners.Remove(stateListener); }
public void SubscribeStateChanges(IZKStateListener listener) { _stateListeners.Add(listener); }
public ZKDistributedDelayLock(ZKClient client, string lockPach) { this.client = client; this.lockPath = lockPach; cancellationTokenSource = new CancellationTokenSource(); factory = new TaskFactory( cancellationTokenSource.Token, TaskCreationOptions.None, TaskContinuationOptions.None, new LimitedConcurrencyLevelTaskScheduler(1)); nodeListener = new ZKDataListener().DataDeleted( (path) => { factory.StartNew(() => { if (!factory.CancellationToken.IsCancellationRequested) { if (!hasLock) { //如果当前没有持有锁 //为了解决网络闪断问题,先等待一段时间,再重新竞争锁 Thread.Sleep(delayTimeMillis); //如果之前获得锁的线程解除了锁定,则所有等待的线程都重新尝试,这里使得信号量加1 semaphore.Release(); } } }, factory.CancellationToken); }); stateListener = new ZKStateListener().StateChanged((state) => { if (state == KeeperState.SyncConnected) { //如果重新连接 factory.StartNew(() => { if (!factory.CancellationToken.IsCancellationRequested) { if (hasLock) { //现在持有锁 //重新创建节点 try { client.Create(lockPath + "/lock", lockNodeData, CreateMode.Ephemeral); } catch (ZKNodeExistsException e) { try { if (lockNodeData != client.ReadData <string>(lockPath + "/lock")) { hasLock = false; } } catch (ZKNoNodeException e2) { //ignore } } } } }, factory.CancellationToken); } }); }
public void UnSubscribeStateChanges(IZKStateListener stateListener) { //Monitor.Enter(_stateListener); _stateListener.Remove(stateListener); //Monitor.Exit(_stateListener); }
public void SubscribeStateChanges(IZKStateListener listener) { //Monitor.Enter(_stateListener); _stateListener.Add(listener); //Monitor.Exit(_stateListener); }