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 public void revalidateSession(QuorumPacket qp, LearnerHandler learnerHandler) throws IOException { ByteArrayInputStream bis = new ByteArrayInputStream(qp.getData()); DataInputStream dis = new DataInputStream(bis); long id = dis.readLong(); int to = dis.readInt(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); dos.writeLong(id); boolean valid = zk.checkIfValidGlobalSession(id, to); if (valid) { try { // set the session owner as the follower that owns the session zk.setOwner(id, learnerHandler); } catch (KeeperException.SessionExpiredException e) { LOG.error("Somehow session " + Long.toHexString(id) + " expired right after being renewed! (impossible)", e); } } if (LOG.isTraceEnabled()) { ZooTrace.logTraceMessage(LOG, ZooTrace.SESSION_TRACE_MASK, "Session 0x" + Long.toHexString(id) + " is valid: "+ valid); } dos.writeBoolean(valid); qp.setData(bos.toByteArray()); learnerHandler.queuePacket(qp); }
Proposal createProposal(long zxid) { Proposal p = new Proposal(); p.packet = new QuorumPacket(); p.packet.setZxid(zxid); p.packet.setType(Leader.PROPOSAL); return p; }
void proposalReceived(QuorumPacket qp) { proposedPkts.add(new QuorumPacket(Leader.INFORM, qp.getZxid(), qp.getData(), null)); }
/** * Create an inform packet and send it to all observers. */ public void inform(Proposal proposal) { QuorumPacket qp = new QuorumPacket(Leader.INFORM, proposal.request.zxid, proposal.packet.getData(), null); sendObserverPacket(qp); }
QuorumPacket qp = new QuorumPacket(); qp.setType(pktType); qp.setZxid(ZxidUtils.makeZxid(self.getAcceptedEpoch(), 0)); BinaryOutputArchive boa = BinaryOutputArchive.getArchive(bsid); boa.writeRecord(li, "LearnerInfo"); qp.setData(bsid.toByteArray()); final long newEpoch = ZxidUtils.getEpochFromZxid(qp.getZxid()); if (qp.getType() == Leader.LEADERINFO) { leaderProtocolVersion = ByteBuffer.wrap(qp.getData()).getInt(); byte epochBytes[] = new byte[4]; final ByteBuffer wrappedEpochBytes = ByteBuffer.wrap(epochBytes); throw new IOException("Leaders epoch, " + newEpoch + " is less than accepted epoch, " + self.getAcceptedEpoch()); QuorumPacket ackNewEpoch = new QuorumPacket(Leader.ACKEPOCH, lastLoggedZxid, epochBytes, null); writePacket(ackNewEpoch, true); return ZxidUtils.makeZxid(newEpoch, 0); 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"); return qp.getZxid();
String mess = null; switch (p.getType()) { case Leader.ACK: type = "ACK"; TxnHeader hdr = new TxnHeader(); try { SerializeUtils.deserializeTxn(p.getData(), hdr); case Leader.REVALIDATE: type = "REVALIDATE"; ByteArrayInputStream bis = new ByteArrayInputStream(p.getData()); DataInputStream dis = new DataInputStream(bis); try { break; default: type = "UNKNOWN" + p.getType(); entry = type + " " + Long.toHexString(p.getZxid()) + " " + mess;
private void proposeSetData(QuorumPacket qp, long zxid, String data, int version) throws IOException { qp.setType(Leader.PROPOSAL); qp.setZxid(zxid); TxnHeader hdr = new TxnHeader(4, 1414, qp.getZxid(), 55, ZooDefs.OpCode.setData); SetDataTxn sdt = new SetDataTxn("/foo", data.getBytes(), version); ByteArrayOutputStream baos = new ByteArrayOutputStream(); OutputArchive boa = BinaryOutputArchive.getArchive(baos); boa.writeRecord(hdr, null); boa.writeRecord(sdt, null); qp.setData(baos.toByteArray()); } });
public static QuorumPacket buildInformAndActivePacket(long zxid, long designatedLeader, byte[] proposalData) { byte[] data = new byte[proposalData.length + 8]; ByteBuffer buffer = ByteBuffer.wrap(data); buffer.putLong(designatedLeader); buffer.put(proposalData); return new QuorumPacket(Leader.INFORMANDACTIVATE, zxid, data, null); }
/** * maintains a list of last <i>committedLog</i> * or so committed requests. This is used for * fast follower synchronization. * @param request committed request */ public void addCommittedProposal(Request request) { WriteLock wl = logLock.writeLock(); try { wl.lock(); if (committedLog.size() > commitLogCount) { committedLog.removeFirst(); minCommittedLog = committedLog.getFirst().packet.getZxid(); } if (committedLog.isEmpty()) { minCommittedLog = request.zxid; maxCommittedLog = request.zxid; } byte[] data = SerializeUtils.serializeRequest(request); QuorumPacket pp = new QuorumPacket(Leader.PROPOSAL, request.zxid, data, null); Proposal p = new Proposal(); p.packet = pp; p.request = request; committedLog.add(p); maxCommittedLog = p.packet.getZxid(); } finally { wl.unlock(); } }
private synchronized QuorumPacket removeProposedPacket(long zxid) { QuorumPacket pkt = proposedPkts.peek(); if (pkt == null || pkt.getZxid() > zxid) { LOG.debug("ignore missing proposal packet for {}", Long.toHexString(zxid)); return null; } if (pkt.getZxid() != zxid) { final String m = String.format("Unexpected proposal packet on commit ack, expected zxid 0x%d got zxid 0x%d", zxid, pkt.getZxid()); LOG.error(m); throw new RuntimeException(m); } proposedPkts.remove(); return pkt; }
static long packetSize(QuorumPacket p) { /* Approximate base size of QuorumPacket: int + long + byte[] + List */ long size = 4 + 8 + 8 + 8; byte[] data = p.getData(); if (data != null) { size += data.length; } return size; }
/** * 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); } }
switch (qp.getType()) { case Leader.PING: ping(qp); case Leader.INFORM: TxnHeader hdr = new TxnHeader(); Record txn = SerializeUtils.deserializeTxn(qp.getData(), hdr); Request request = new Request (null, hdr.getClientId(), hdr.getCxid(), break; default: LOG.error("Invalid packet type: {} received by Observer", qp.getType());
protected void ping(QuorumPacket qp) throws IOException { // Send back the ping with our session data ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); Map<Long, Integer> touchTable = zk.getTouchSnapshot(); for (Entry<Long, Integer> entry : touchTable.entrySet()) { dos.writeLong(entry.getKey()); dos.writeInt(entry.getValue()); } qp.setData(bos.toByteArray()); writePacket(qp, true); }
public void write(java.io.DataOutput out) throws java.io.IOException { BinaryOutputArchive archive = new BinaryOutputArchive(out); serialize(archive, ""); } public void readFields(java.io.DataInput in) throws java.io.IOException {
public void readFields(java.io.DataInput in) throws java.io.IOException { BinaryInputArchive archive = new BinaryInputArchive(in); deserialize(archive, ""); } public int compareTo (Object peer_) throws ClassCastException {
QuorumPacket qp = new QuorumPacket(); qp.setType(pktType); qp.setZxid(ZxidUtils.makeZxid(self.getAcceptedEpoch(), 0)); BinaryOutputArchive boa = BinaryOutputArchive.getArchive(bsid); boa.writeRecord(li, "LearnerInfo"); qp.setData(bsid.toByteArray()); final long newEpoch = ZxidUtils.getEpochFromZxid(qp.getZxid()); if (qp.getType() == Leader.LEADERINFO) { leaderProtocolVersion = ByteBuffer.wrap(qp.getData()).getInt(); byte epochBytes[] = new byte[4]; final ByteBuffer wrappedEpochBytes = ByteBuffer.wrap(epochBytes); throw new IOException("Leaders epoch, " + newEpoch + " is less than accepted epoch, " + self.getAcceptedEpoch()); QuorumPacket ackNewEpoch = new QuorumPacket(Leader.ACKEPOCH, lastLoggedZxid, epochBytes, null); writePacket(ackNewEpoch, true); return ZxidUtils.makeZxid(newEpoch, 0); 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"); return qp.getZxid();
Record txn = null; switch (p.getType()) { case Leader.ACK: type = "ACK"; TxnHeader hdr = new TxnHeader(); try { SerializeUtils.deserializeTxn(p.getData(), hdr); case Leader.REVALIDATE: type = "REVALIDATE"; ByteArrayInputStream bis = new ByteArrayInputStream(p.getData()); DataInputStream dis = new DataInputStream(bis); try { break; default: type = "UNKNOWN" + p.getType(); entry = type + " " + Long.toHexString(p.getZxid()) + " " + mess;