www

导航

zookeeper选举(三)-WorkerReceiver

  Messenger.WorkerReceiver
  接收投票信息工作线程

    class WorkerReceiver extends ZooKeeperThread {
            volatile boolean stop;
            QuorumCnxManager manager;
            WorkerReceiver(QuorumCnxManager manager) {
                super("WorkerReceiver");
                this.stop = false;
                this.manager = manager;
            }

            public void run() {
                Message response;
                while (!stop) {
                    try {
                        response = manager.pollRecvQueue();
                        if (response == null) continue;

                        // 如果是观察者-currentVote投票信息发过去(两种情况,1:当前节点,2:选主结束后的投票信息)
                        if (!validVoter(response.sid)) {
                            Vote current = self.getCurrentVote();
                            // response.sid为对方节点myid
                            ToSend notMsg = new ToSend(current.getId(), current.getZxid(), logicalClock.get(),
                                    self.getPeerState(), response.sid, current.getPeerEpoch());
                            sendQueue.offer(notMsg);
                        } else {
                            if (response.buffer.capacity() < 28) {
                                LOG.error("Got a short response: " + response.buffer.capacity());
                                continue;
                            }
                            boolean backCompatibility = (response.buffer.capacity() == 28);
                            response.buffer.clear();

                            Notification n = new Notification();

                            // 当方节点当前选举状态
                            QuorumPeer.ServerState ackState;
                            switch (response.buffer.getInt()) {
                                case 0:
                                    ackState = QuorumPeer.ServerState.LOOKING;
                                    break;
                                case 1:
                                    ackState = QuorumPeer.ServerState.FOLLOWING;
                                    break;
                                case 2:
                                    ackState = QuorumPeer.ServerState.LEADING;
                                    break;
                                case 3:
                                    ackState = QuorumPeer.ServerState.OBSERVING;
                                    break;
                                default:
                                    continue;
                            }
                            // 反序列化,获取对方节点发送过来的投票信息
                            n.leader = response.buffer.getLong();
                            n.zxid = response.buffer.getLong();
                            n.electionEpoch = response.buffer.getLong();
                            n.state = ackState;
                            n.sid = response.sid;
                            if (!backCompatibility) {
                                n.peerEpoch = response.buffer.getLong();
                            } else {
                                n.peerEpoch = ZxidUtils.getEpochFromZxid(n.zxid);
                            }

                            n.version = (response.buffer.remaining() >= 4) ?
                                    response.buffer.getInt() : 0x0;

                            // 如果当前节点状态是LOOKING
                            if (self.getPeerState() == QuorumPeer.ServerState.LOOKING) {
                                // 加入接收投票信息队列
                                recvQueue.offer(n);
                                // 如果对方节点状态是LOOKING,并且electionEpoch小于当前节点的选举轮次,直接把当前节点的投票信息发送过去
                                if ((ackState == QuorumPeer.ServerState.LOOKING) && (n.electionEpoch < logicalClock.get())) {
                                    Vote v = getVote();
                                    ToSend notMsg = new ToSend(v.getId(), v.getZxid(), logicalClock.get(),
                                            self.getPeerState(), response.sid, v.getPeerEpoch());
                                    sendQueue.offer(notMsg);
                                }
                            } else {
                                // 当前节点已经选主结束-currentVote
                                Vote current = self.getCurrentVote();
                                if (ackState == QuorumPeer.ServerState.LOOKING) {
                                    ToSend notMsg;
                                    if (n.version > 0x0) {
                                        notMsg = new ToSend(
                                                current.getId(),
                                                current.getZxid(),
                                                current.getElectionEpoch(),
                                                self.getPeerState(),
                                                response.sid,
                                                current.getPeerEpoch());
                                    } else {
                                        Vote bcVote = self.getBCVote();
                                        notMsg = new ToSend(
                                                bcVote.getId(),
                                                bcVote.getZxid(),
                                                bcVote.getElectionEpoch(),
                                                self.getPeerState(),
                                                response.sid,
                                                bcVote.getPeerEpoch());
                                    }
                                    sendQueue.offer(notMsg);
                                }
                            }
                        }
                    } catch (InterruptedException e) {
                        //
                    }
                }
                LOG.info("WorkerReceiver is down");
            }
        }
  

posted on 2020-09-30 15:26  www_practice  阅读(225)  评论(0编辑  收藏  举报