/** * Constructs a SyncProposalProcessor object. * * @param persistence the persistent variables. * @param transport used to send acknowledgment. * @param maxBatchSize the maximum batch size. * @throws IOException in case of IO failure. */ public SyncProposalProcessor(PersistentState persistence, Transport transport, int maxBatchSize) throws IOException { this.persistence = persistence; this.log = persistence.getLog(); this.transport = transport; this.maxBatchSize = maxBatchSize; this.serverId = persistence.getLastSeenConfig().getServerId(); ExecutorService es = Executors.newSingleThreadExecutor(DaemonThreadFactory.FACTORY); ft = es.submit(this); es.shutdown(); }
@Override public Void call() throws Exception { try { LOG.debug("Batched SyncRequestProcessor gets started."); MessageTuple lastReq = null; // Number of transactions batched so far. int batchCount = 0; while (true) { MessageTuple req; if (lastReq == null) { req = this.proposalQueue.take(); } else { req = this.proposalQueue.poll(); if (req == null || batchCount == maxBatchSize || req == MessageTuple.REQUEST_OF_DEATH) { // Sync to disk and send ACK to leader. this.log.sync(); Zxid zxid = MessageBuilder.fromProtoZxid(lastReq.getMessage().getProposal().getZxid()); sendAck(lastReq.getServerId(), zxid); batchCount = 0; } } if (req == MessageTuple.REQUEST_OF_DEATH) { break; } if (req == null) { lastReq = null; continue; } if (req.getMessage().getType() == MessageType.PROPOSAL) { // It's PROPOSAL, sync to disk. Message msg = req.getMessage(); Transaction txn = MessageBuilder.fromProposal(msg.getProposal()); // TODO : avoid this? ByteBuffer body = txn.getBody().asReadOnlyBuffer(); LOG.debug("Syncing transaction {} to disk.", txn.getZxid()); this.log.append(txn); batchCount++; lastReq = req; if (txn.getType() == ProposalType.COP_VALUE) { // If it's COP, we should also update cluster_config file. ClusterConfiguration cnf = ClusterConfiguration.fromByteBuffer(body, this.serverId); persistence.setLastSeenConfig(cnf); // If it's COP, we shouldn't batch it, send ACK immediatly. sendAck(req.getServerId(), txn.getZxid()); batchCount = 0; lastReq = null; } } } } catch (Exception e) { LOG.error("Caught an exception in SyncProposalProcessor", e); throw e; } LOG.debug("SyncProposalProcessor has been shut down."); return null; }