@Override public String toString() { return packet.getType() + ", " + packet.getZxid() + ", " + request; } }
@Override public String toString() { return packet.getType() + ", " + packet.getZxid() + ", " + request; } }
/** * read a packet from the leader * * @param pp * the packet to be instantiated * @throws IOException */ void readPacket(QuorumPacket pp) throws IOException { synchronized (leaderIs) { leaderIs.readRecord(pp, "packet"); } long traceMask = ZooTrace.SERVER_PACKET_TRACE_MASK; if (pp.getType() == Leader.PING) { traceMask = ZooTrace.SERVER_PING_TRACE_MASK; } if (LOG.isTraceEnabled()) { ZooTrace.logQuorumPacket(LOG, traceMask, 'i', pp); } }
@Override protected void processPacket(QuorumPacket qp) throws Exception { if (stopPing && qp.getType() == Leader.PING) { LOG.info("Follower skipped ping"); throw new SocketException("Socket time out while sending the ping response"); } else { super.processPacket(qp); } } };
static void readPacketSkippingPing(InputArchive ia, QuorumPacket qp) throws IOException { while(true) { ia.readRecord(qp, null); if (qp.getType() != Leader.PING) { return; } } }
/** * read a packet from the leader * * @param pp * the packet to be instantiated * @throws IOException */ void readPacket(QuorumPacket pp) throws IOException { synchronized (leaderIs) { leaderIs.readRecord(pp, "packet"); } long traceMask = ZooTrace.SERVER_PACKET_TRACE_MASK; if (pp.getType() == Leader.PING) { traceMask = ZooTrace.SERVER_PING_TRACE_MASK; } if (LOG.isTraceEnabled()) { ZooTrace.logQuorumPacket(LOG, traceMask, 'i', pp); } }
@Override void writePacket(QuorumPacket pp, boolean flush) throws IOException { if (pp != null && pp.getType() == Leader.ACK) { newLeaderMessage = true; try { /** * Delaying the ACK message, a follower sends as * response to a NEWLEADER message, so that the * leader has a chance to send the reconfig and only * then the UPTODATE message. */ Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } super.writePacket(pp, flush); } };
boolean revalidateLearnerSession(QuorumPacket qp) throws IOException { ByteArrayInputStream bis = new ByteArrayInputStream(qp.getData()); DataInputStream dis = new DataInputStream(bis); long id = dis.readLong(); boolean valid = dis.readBoolean(); Iterator<Revalidation> itr = pendingRevalidations.iterator(); if (!itr.hasNext()) { // not a learner session, handle locally return false; } Revalidation revalidation = itr.next(); if (revalidation.sessionId != id) { // not a learner session, handle locally return false; } itr.remove(); LearnerHandler learnerHandler = revalidation.handler; // create a copy here as the qp object is reused by the Follower and may be mutated QuorumPacket deepCopy = new QuorumPacket(qp.getType(), qp.getZxid(), Arrays.copyOf(qp.getData(), qp.getData().length), qp.getAuthinfo() == null ? null : new ArrayList<>(qp.getAuthinfo())); learnerHandler.queuePacket(deepCopy); // To keep consistent as leader, touch the session when it's // revalidating the session, only update if it's a valid session. if (valid) { touch(revalidation.sessionId, revalidation.timeout); } return true; }
@Override void writePacket(QuorumPacket pp, boolean flush) throws IOException { if (pp != null && pp.getType() == Leader.ACK && context.exitWhenAckNewLeader) { if (context.newLeaderAckCallback != null) { context.newLeaderAckCallback.start(); } } super.writePacket(pp, flush); } };
@Override void readPacket(QuorumPacket pp) throws IOException { /** * In real scenario got SocketTimeoutException while reading * the packet from leader because of network problem, but * here throwing SocketTimeoutException based on whether * error is injected or not */ super.readPacket(pp); if (injectError && pp.getType() == Leader.PROPOSAL) { String type = LearnerHandler.packetToString(pp); throw new SocketTimeoutException( "Socket timeout while reading the packet for operation " + type); } }
/** * Check if op packet (first packet in the queue) match the expected value * @param type - type of packet * @param zxid - zxid in the op packet * @param currentZxid - last packet queued by syncFollower, * before invoking startForwarding() */ public void assertOpType(int type, long zxid, long currentZxid) { Queue<QuorumPacket> packets = learnerHandler.getQueuedPackets(); assertTrue(packets.size() > 0); assertEquals(type, packets.peek().getType()); assertZxidEquals(zxid, packets.peek().getZxid()); assertZxidEquals(currentZxid, this.currentZxid); }
/** * Validate that queued packets contains proposal in the following orders as * a given array of zxids * * @param zxids */ public void queuedPacketMatches(long[] zxids) { int index = 0; for (QuorumPacket qp : learnerHandler.getQueuedPackets()) { if (qp.getType() == Leader.PROPOSAL) { assertZxidEquals(zxids[index++], qp.getZxid()); } } }
switch (qp.getType()) { case Leader.PING: ping(qp);
readPacket(qp); final long newEpoch = ZxidUtils.getEpochFromZxid(qp.getZxid()); if (qp.getType() == Leader.LEADERINFO) { self.setAcceptedEpoch(newEpoch); if (qp.getType() != Leader.NEWLEADER) { LOG.error("First packet should have been NEWLEADER"); throw new IOException("First packet should have been NEWLEADER");
public void converseWithLeader(InputArchive ia, OutputArchive oa, Leader l) throws IOException, InterruptedException { /* we test a normal run. everything should work out well. */ LearnerInfo li = new LearnerInfo(1, 0x10000, 0); byte liBytes[] = new byte[20]; ByteBufferOutputStream.record2ByteBuffer(li, ByteBuffer.wrap(liBytes)); QuorumPacket qp = new QuorumPacket(Leader.FOLLOWERINFO, 0, liBytes, null); oa.writeRecord(qp, null); readPacketSkippingPing(ia, qp); Assert.assertEquals(Leader.LEADERINFO, qp.getType()); Assert.assertEquals(ZxidUtils.makeZxid(1, 0), qp.getZxid()); Assert.assertEquals(ByteBuffer.wrap(qp.getData()).getInt(), 0x10000); Thread.sleep(l.self.getInitLimit()*l.self.getTickTime() + 5000); // The leader didn't get a quorum of acks - make sure that leader's current epoch is not advanced Assert.assertEquals(0, l.self.getCurrentEpoch()); } });
public void converseWithLeader(InputArchive ia, OutputArchive oa, Leader l) throws IOException { /* we test a normal run. everything should work out well. */ LearnerInfo li = new LearnerInfo(1, 0x10000, 0); byte liBytes[] = new byte[20]; ByteBufferOutputStream.record2ByteBuffer(li, ByteBuffer.wrap(liBytes)); /* we are going to say we last acked epoch 20 */ QuorumPacket qp = new QuorumPacket(Leader.FOLLOWERINFO, ZxidUtils.makeZxid(20, 0), liBytes, null); oa.writeRecord(qp, null); readPacketSkippingPing(ia, qp); Assert.assertEquals(Leader.LEADERINFO, qp.getType()); Assert.assertEquals(ZxidUtils.makeZxid(21, 0), qp.getZxid()); Assert.assertEquals(ByteBuffer.wrap(qp.getData()).getInt(), 0x10000); qp = new QuorumPacket(Leader.ACKEPOCH, 0, new byte[4], null); oa.writeRecord(qp, null); readPacketSkippingPing(ia, qp); Assert.assertEquals(Leader.DIFF, qp.getType()); readPacketSkippingPing(ia, qp); Assert.assertEquals(Leader.NEWLEADER, qp.getType()); Assert.assertEquals(ZxidUtils.makeZxid(21, 0), qp.getZxid()); qp = new QuorumPacket(Leader.ACK, qp.getZxid(), null, null); oa.writeRecord(qp, null); readPacketSkippingPing(ia, qp); Assert.assertEquals(Leader.UPTODATE, qp.getType()); } });
@Override public void converseWithLeader(InputArchive ia, OutputArchive oa, Leader l, long zxid) throws Exception { Assert.assertEquals(1, l.self.getAcceptedEpoch()); Assert.assertEquals(1, l.self.getCurrentEpoch()); /* we test a normal run. everything should work out well. */ LearnerInfo li = new LearnerInfo(1, 0x10000, 0); byte liBytes[] = new byte[20]; ByteBufferOutputStream.record2ByteBuffer(li, ByteBuffer.wrap(liBytes)); QuorumPacket qp = new QuorumPacket(Leader.FOLLOWERINFO, 1, liBytes, null); oa.writeRecord(qp, null); readPacketSkippingPing(ia, qp); Assert.assertEquals(Leader.LEADERINFO, qp.getType()); Assert.assertEquals(ZxidUtils.makeZxid(2, 0), qp.getZxid()); Assert.assertEquals(ByteBuffer.wrap(qp.getData()).getInt(), 0x10000); Assert.assertEquals(2, l.self.getAcceptedEpoch()); Assert.assertEquals(1, l.self.getCurrentEpoch()); byte epochBytes[] = new byte[4]; final ByteBuffer wrappedEpochBytes = ByteBuffer.wrap(epochBytes); wrappedEpochBytes.putInt(1); qp = new QuorumPacket(Leader.ACKEPOCH, zxid, epochBytes, null); oa.writeRecord(qp, null); readPacketSkippingPing(ia, qp); Assert.assertEquals(Leader.DIFF, qp.getType()); } }, 2);
Assert.assertEquals(Leader.LEADERINFO, qp.getType()); Assert.assertEquals(ZxidUtils.makeZxid(1, 0), qp.getZxid()); Assert.assertEquals(ByteBuffer.wrap(qp.getData()).getInt(), Assert.assertEquals(Leader.DIFF, qp.getType()); Assert.assertEquals(Leader.NEWLEADER, qp.getType()); Assert.assertEquals(ZxidUtils.makeZxid(1, 0), qp.getZxid()); Assert.assertEquals(1, l.self.getAcceptedEpoch()); Assert.assertEquals(Leader.UPTODATE, qp.getType());
Assert.assertEquals(Leader.LEADERINFO, qp.getType()); Assert.assertEquals(ZxidUtils.makeZxid(1, 0), qp.getZxid()); Assert.assertEquals(ByteBuffer.wrap(qp.getData()).getInt(), Assert.assertEquals(Leader.DIFF, qp.getType()); Assert.assertEquals(Leader.NEWLEADER, qp.getType()); Assert.assertEquals(ZxidUtils.makeZxid(1, 0), qp.getZxid()); Assert.assertEquals(1, l.self.getAcceptedEpoch()); Assert.assertEquals(Leader.UPTODATE, qp.getType()); Assert.assertEquals(Leader.PROPOSAL, qp.getType());