/** * Blocks until the requested index is committed. * * @param timeout -1 means there is no timeout. * @param index must be greater than 0. */ public void getCommittedLogEntry(CoreCmd ccmd, int index, int timeout) throws InterruptedException, GondolaException, TimeoutException { commitQueue.get(ccmd, index, timeout); }
public void stop() { peers.forEach(p -> p.stop()); saveQueue.stop(); commitQueue.stop(); threads.forEach(t -> t.interrupt()); for (Thread t : threads) { try { t.join(); } catch (InterruptedException e) { logger.error(e.getMessage(), e); } } threads.clear(); }
/** * @throw Exception Is thrown when some thread cannot be started. The state of the instance is not known. */ public void start() throws GondolaException { if (threads.size() > 0) { throw new IllegalStateException("start() can only be called once"); } for (Peer peer : peers.values()) { peer.start(); } // Start local threads saveQueue.start(); commitQueue.start(); threads.add(new MainLoop()); threads.add(new CommandHandler()); threads.forEach(t -> t.start()); }
/** * Called as a result of incoming append entry reply messages. * Attempts to release as many waiting commands as possible. */ void updateWaitingCommands() throws Exception { int index = commitIndex; if (isLeader()) { // Commit CoreCmd ccmd = waitQueue.peek(); while (ccmd != null && ccmd.index <= index) { latency.tail(ccmd.index); ccmd.update(Command.STATUS_OK, leaderId); waitQueue.poll(); ccmd = waitQueue.peek(); } } // Update the getters saveQueue.getLatest(savedRid, false); index = Math.min(commitIndex, savedRid.index); // The min is needed for followers commitQueue.updateCommitIndex(index); }
public CoreMember(Gondola gondola, Cluster cluster, int memberId, List<Integer> peerIds, boolean isPrimary) throws Exception { this.gondola = gondola; this.cluster = cluster; this.memberId = memberId; this.isPrimary = isPrimary; gondola.getConfig().registerForUpdates(this); acquireFileLock(); clock = gondola.getClock(); pool = gondola.getMessagePool(); storage = gondola.getStorage(); incomingQueue = new ArrayBlockingQueue<>(incomingQueueSize); saveQueue = new SaveQueue(gondola, this); commitQueue = new CommitQueue(gondola, this); for (int id : peerIds) { Peer peer = new Peer(gondola, this, id); peers.add(peer); peerMap.put(peer.peerId, peer); } // Initialize some convenience variables for use when calculating the commit index majority = (peers.size() + 1) / 2 + 1; matchIndices = new int[peers.size()]; reset(); }
/** * @throw Exception Is thrown when some thread cannot be started. The state of the instance is not known. */ public void start() throws Exception { reset(); for (Peer peer : peers) { peer.start(); } // Start local threads assert threads.size() == 0; saveQueue.start(); commitQueue.start(); threads.add(new MainLoop()); threads.add(new CommandHandler()); threads.forEach(t -> t.start()); }
/** * Called as a result of incoming append entry reply messages. Attempts to release as many waiting commands as * possible. */ void updateWaitingCommands() { int index = commitIndex; if (isLeader()) { // Commit CoreCmd ccmd = waitQueue.peek(); while (ccmd != null && ccmd.index <= index) { latency.tail(ccmd.index); ccmd.update(Command.STATUS_OK, leaderId); waitQueue.poll(); ccmd = waitQueue.peek(); } } // Update the getters saveQueue.getLatest(savedRid); index = Math.min(commitIndex, savedRid.index); // The min is needed for followers commitQueue.updateCommitIndex(index); }
public CoreMember(Gondola gondola, Shard shard, int memberId, List<Integer> peerIds, boolean isPrimary) throws GondolaException { this.gondola = gondola; this.shard = shard; this.memberId = memberId; this.peerIds = peerIds; this.isPrimary = isPrimary; gondola.getConfig().registerForUpdates(configListener); // Acquire file lock to prevent another process running with the same member id try { fileLock(true); } catch (IOException e) { throw new GondolaException(e); } clock = gondola.getClock(); pool = gondola.getMessagePool(); storage = gondola.getStorage(); incomingQueue = new ArrayBlockingQueue<>(incomingQueueSize); saveQueue = new SaveQueue(gondola, this); commitQueue = new CommitQueue(gondola, this); gondola.getNetwork().register(memberId, channel -> acceptSlaveConnection(channel)); peerIds.forEach(id -> peers.put(id, new Peer(gondola, this, id))); // Initialize some convenience variables for use when calculating the commit index majority = (peers.size() + 1) / 2 + 1; matchIndices = new int[peers.size()]; reset(); }
/** * Blocks until the requested index is committed. * * @param timeout -1 means there is no timeout. * @param index must be greater than 0. */ public void getCommittedLogEntry(CoreCmd ccmd, int index, int timeout) throws Exception { commitQueue.get(ccmd, index, timeout); }
public boolean stop() { boolean status = true; for (Peer peer : peers.values()) { status = peer.stop() && status; } for (Peer slave : slaves) { status = slave.stop() && status; } status = saveQueue.stop() && status; status = commitQueue.stop() && status; status = Utils.stopThreads(threads) && status; try { fileLock(false); } catch (IOException e) { logger.error("Could not release file lock", e); status = false; } return status; }