/** * Only used by QuorumStats at the moment */ public String[] getQuorumPeers() { List<String> l = new ArrayList<String>(); synchronized (this) { if (leader != null) { for (LearnerHandler fh : leader.getLearners()) { if (fh.getSocket() != null) { String s = formatInetAddr((InetSocketAddress)fh.getSocket().getRemoteSocketAddress()); if (leader.isLearnerSynced(fh)) s += "*"; l.add(s); } } } else if (follower != null) { l.add(formatInetAddr((InetSocketAddress)follower.sock.getRemoteSocketAddress())); } } return l.toArray(new String[0]); }
public void run() { ServerSocket ss; synchronized(this) { ss = this.ss; } while (listenerRunning) { try { Socket s = ss.accept(); // start with the initLimit, once the ack is processed // in LearnerHandler switch to the syncLimit s.setSoTimeout(self.tickTime * self.initLimit); BufferedInputStream is = new BufferedInputStream(s.getInputStream()); LearnerHandler lh = new LearnerHandler(s, is, this); lh.start(); } catch (Exception e) { if (listenerRunning) { LOG.debug("Ignoring accept exception (maybe shutting down)", e); } else { LOG.debug("Ignoring accept exception (maybe client closed)", e); } } } /* * we don't need to close ss because we only got here because listenerRunning is * false and that is set and then ss is closed() in stop() */ }
continue; handler.queuePacket(p.packet); handler.queuePacket(qp); if (handler.getLearnerType() == LearnerType.PARTICIPANT) { List<Long>zxids = new ArrayList<Long>(outstandingProposals.keySet()); Collections.sort(zxids); continue; handler.queuePacket(outstandingProposals.get(zxid).packet); if (handler.getLearnerType() == LearnerType.PARTICIPANT) { addForwardingFollower(handler); } else {
public String followerInfo() { StringBuilder sb = new StringBuilder(); for (LearnerHandler handler : leader.getLearners()) { if (handler.getLearnerType() == LearnerType.PARTICIPANT) { sb.append(handler.toString()).append("\n"); } } return sb.toString(); }
/** * Returns true if a quorum in qv is connected and synced with the leader * and false otherwise * * @param qv, a QuorumVerifier */ public boolean isQuorumSynced(QuorumVerifier qv) { HashSet<Long> ids = new HashSet<Long>(); if (qv.getVotingMembers().containsKey(self.getId())) ids.add(self.getId()); synchronized (forwardingFollowers) { for (LearnerHandler learnerHandler: forwardingFollowers){ if (learnerHandler.synced() && qv.getVotingMembers().containsKey(learnerHandler.getSid())){ ids.add(learnerHandler.getSid()); } } } return qv.containsQuorum(ids); }
StateSummary ss = null; long zxid = qp.getZxid(); long newEpoch = learnerMaster.getEpochToPropose(this.getSid(), lastAcceptedEpoch); long newLeaderZxid = ZxidUtils.makeZxid(newEpoch, 0); if (this.getVersion() < 0x10000) { learnerMaster.waitForEpochAck(this.getSid(), ss); } else { byte ver[] = new byte[4]; learnerMaster.waitForEpochAck(this.getSid(), ss); boolean needSnap = syncFollower(peerLastZxid, learnerMaster); boolean exemptFromThrottle = getLearnerType() != LearnerType.OBSERVER; LearnerSnapshot snapshot = learnerMaster.getLearnerSnapshotThrottler().beginSnapshot(exemptFromThrottle); if (getVersion() < 0x10000) { QuorumPacket newLeaderQP = new QuorumPacket(Leader.NEWLEADER, newLeaderZxid, null, null); startSendingPackets(); if(qp.getType() != Leader.ACK){ LOG.error("Next packet was supposed to be an ACK," + " but received packet: {}", packetToString(qp)); return;
StateSummary ss = null; long zxid = qp.getZxid(); long newEpoch = leader.getEpochToPropose(this.getSid(), lastAcceptedEpoch); if (this.getVersion() < 0x10000) { leader.waitForEpochAck(this.getSid(), ss); } else { byte ver[] = new byte[4]; leader.waitForEpochAck(this.getSid(), ss); queuePacket(propose.packet); QuorumPacket qcommit = new QuorumPacket(Leader.COMMIT, propose.packet.getZxid(), null, null); queuePacket(qcommit); if (getVersion() < 0x10000) { oa.writeRecord(newLeaderQP, "packet"); } else { LOG.info("Received NEWLEADER-ACK message from " + getSid()); leader.waitForNewLeaderAck(getSid(), qp.getZxid()); while(!leader.zk.isRunning() && !this.isInterrupted()){ leader.zk.wait(20); break; default:
HashSet<Long> followerSet = new HashSet<Long>(); for (LearnerHandler f : learners) followerSet.add(f.getSid()); if (f.synced() && f.getLearnerType() == LearnerType.PARTICIPANT) { syncedSet.add(f.getSid()); f.ping();
if (packet.getZxid() > lastSeenZxid + 1) { LOG.error("LearnerHandler is too far behind ({} < {}), disconnecting {} at {}", Long.toHexString(lastSeenZxid + 1), Long.toHexString(packet.getZxid()), learnerHandler.getSid(), learnerHandler.getRemoteAddress()); learnerHandler.shutdown(); return -1; } else if (packet.getZxid() == lastSeenZxid + 1) { learnerHandler.queuePacket(packet); long queueBytesUsed = LearnerHandler.packetSize(packet); while (itr.hasNext()) { packet = itr.next(); continue; learnerHandler.queuePacket(packet); queueBytesUsed += LearnerHandler.packetSize(packet); learnerHandler.getSid(), Long.toHexString(queueHeadZxid), Long.toHexString(packet.getZxid()),
when(follower.getLearnerType()).thenReturn(LearnerType.PARTICIPANT); when(follower.toString()).thenReturn("1"); when(follower.getSid()).thenReturn(1L); leader.addLearnerHandler(follower); leader.addForwardingFollower(follower); when(observer.getLearnerType()).thenReturn(LearnerType.OBSERVER); when(observer.toString()).thenReturn("2"); leader.addLearnerHandler(observer); when(nonVotingFollower.getLearnerType()).thenReturn(LearnerType.PARTICIPANT); when(nonVotingFollower.toString()).thenReturn("5"); when(nonVotingFollower.getSid()).thenReturn(5L); leader.addLearnerHandler(nonVotingFollower); leader.addForwardingFollower(nonVotingFollower);
/** * send a packet to all the followers ready to follow * * @param qp * the packet to be sent */ void sendPacket(QuorumPacket qp) { synchronized (forwardingFollowers) { for (LearnerHandler f : forwardingFollowers) { f.queuePacket(qp); } } }
/** * ping calls from the learnerMaster to the peers */ public void ping() { // If learner hasn't sync properly yet, don't send ping packet // otherwise, the learner will crash if (!sendingThreadStarted) { return; } long id; if (syncLimitCheck.check(System.nanoTime())) { id = learnerMaster.getLastProposed(); QuorumPacket ping = new QuorumPacket(Leader.PING, id, null, null); queuePacket(ping); } else { LOG.warn("Closing connection to peer due to transaction timeout."); shutdown(); } }
LOG.info("Sending DIFF zxid=0x" + Long.toHexString(lastCommittedZxid) + " for peer sid: " + getSid()); queueOpPacket(Leader.DIFF, lastCommittedZxid); needOpPacket = false; continue; " for peer sid: " + getSid()); queueOpPacket(Leader.DIFF, lastCommittedZxid); needOpPacket = false; } else if (packetZxid > peerLastZxid ) { LOG.warn("Cannot send TRUNC to peer sid: " + getSid() + " peer zxid is from different epoch" ); return queuedZxid; " for peer sid: " + getSid()); queueOpPacket(Leader.TRUNC, prevProposalZxid); needOpPacket = false; queuePacket(propose.packet); queueOpPacket(Leader.COMMIT, packetZxid); queuedZxid = packetZxid; " for peer sid: " + getSid()); queueOpPacket(Leader.DIFF, lastCommittedZxid); needOpPacket = false;
static public void logQuorumPacket(Logger log, long mask, char direction, QuorumPacket qp) { if (isTraceEnabled(log, mask)) { logTraceMessage(log, mask, direction + " " + LearnerHandler.packetToString(qp)); } }
@Override public String toString() { return "LearnerHandlerBean{remoteIP=" + remoteAddr + ",ServerId=" + learnerHandler.getSid() + "}"; } }
@Override public String nonVotingFollowerInfo() { StringBuilder sb = new StringBuilder(); for (LearnerHandler handler : leader.getNonVotingFollowers()) { sb.append(handler.toString()).append("\n"); } return sb.toString(); }
+ " peerLastZxid=0x{}", getSid(), Long.toHexString(maxCommittedLog), Long.toHexString(minCommittedLog), " for peer sid: " + getSid()); queueOpPacket(Leader.DIFF, peerLastZxid); needOpPacket = false; needSnap = false; " for peer sid:" + getSid()); queueOpPacket(Leader.TRUNC, maxCommittedLog); currentZxid = maxCommittedLog; needOpPacket = false; LOG.info("Using committedLog for peer sid: " + getSid()); Iterator<Proposal> itr = db.getCommittedLog().iterator(); currentZxid = queueCommittedProposals(itr, peerLastZxid, null, maxCommittedLog); needSnap = false; peerLastZxid, sizeLimit); if (txnLogItr.hasNext()) { LOG.info("Use txnlog and committedLog for peer sid: " + getSid()); currentZxid = queueCommittedProposals(txnLogItr, peerLastZxid, minCommittedLog, maxCommittedLog); currentZxid = queueCommittedProposals(committedLogItr, currentZxid, null, maxCommittedLog); needSnap = false;
public boolean synced() { return isAlive() && leader.self.tick.get() <= tickOfNextAckDeadline; } }
@Override public void run() { for (LearnerHandler lh: activeObservers) { lh.ping(); } } };