ReplicaSnapshot snapshot() { ReplicaSnapshot s = new ReplicaSnapshot(this); s.accepted = txnAccepted; s.committed = txnCommitted; s.state = state; s.error = error; s.retryAtMillis = waitingForRetry() ? retryAtMillis : 0; return s; }
private static void debug(StringBuilder b, ReplicaSnapshot s) { KetchReplica replica = s.getReplica(); debug(b, replica.getName(), s.getAccepted(), s.getCommitted()); b.append(String.format(" %-8s %s", //$NON-NLS-1$ replica.getParticipation(), s.getState())); if (s.getState() == OFFLINE) { String err = s.getErrorMessage(); if (err != null) { b.append(" (").append(err).append(')'); //$NON-NLS-1$ } } }
@Override public void run() { MonotonicClock clk = getSystem().getClock(); try (Repository git = getLeader().openRepository(); ProposedTimestamp ts = clk.propose()) { try { update(git, req, ts); req.done(git); } catch (Throwable err) { req.setException(git, err); } } catch (IOException err) { req.setException(null, err); } } });
@Override public void run() { try (Repository git = getLeader().openRepository()) { try { push(git, req); req.done(git); } catch (Throwable err) { req.setException(git, err); } } catch (IOException err) { req.setException(null, err); } } });
private static boolean canCombine(Proposal a, Proposal b) { String aMsg = nullToEmpty(a.getMessage()); String bMsg = nullToEmpty(b.getMessage()); return aMsg.equals(bMsg) && canCombine(a.getAuthor(), b.getAuthor()); }
private void waitForPropose(Proposal proposal, ProgressSpinner spinner) throws InterruptedException { spinner.beginTask(KetchText.get().proposingUpdates, 2, SECONDS); while (!proposal.await(250, MILLISECONDS)) { spinner.update(); } spinner.endTask(proposal.getState() == EXECUTED ? KetchText.get().accepted : KetchText.get().failed); } }
void pushCommitAsync(LogIndex committed) { List<ReceiveCommand> cmds = new ArrayList<>(); prepareTxnCommitted(cmds, committed); pushAsync(new ReplicaPushRequest(this, cmds)); }
/** * Read a configuration from a config block. * * @param cfg * configuration to read. * @param name * of the replica being configured. * @return replica configuration for {@code name}. */ public static ReplicaConfig newFromConfig(Config cfg, String name) { return new ReplicaConfig().fromConfig(cfg, name); }
/** * Asynchronously distribute the round's new value for * {@code refs/txn/accepted} to all replicas. * <p> * Invoked by {@link #start()} after new commits have been created for the * log. The method passes {@code newId} to {@link KetchLeader} to be * distributed to all known replicas. * * @param newId * new value for {@code refs/txn/accepted}. */ void runAsync(AnyObjectId newId) { acceptedNewIndex = acceptedOldIndex.nextIndex(newId); leader.runAsync(this); }
private void blockUntil(ProposedTimestamp ts) throws IOException { try { ts.blockUntil(getSystem().getMaxWaitForMonotonicClock()); } catch (InterruptedException | TimeoutException e) { throw new TimeIsUncertainException(e); } } }
LagCheck(KetchReplica replica, Repository repo) { this.replica = replica; this.repo = repo; initRevWalk(); }
@Override void success() { for (Proposal p : todo) { p.success(); } }
/** * Get description of this replica for error/debug logging purposes. * * @return description of this replica for error/debug logging purposes. */ protected String describeForLog() { return getName(); }
void abort() { for (Proposal p : todo) { p.abort(); } }
@Override public Void call() throws Exception { KetchReplica r = get(); if (r != null) { r.doRetryPush(); } return null; } }
boolean hasAccepted(LogIndex id) { return equals(txnAccepted, id); }
boolean shouldPushUnbatchedCommit(LogIndex committed, boolean leaderIdle) { return (leaderIdle || commitSpeed == FAST) && hasAccepted(committed); }
static LogIndex unknown(AnyObjectId id) { return new LogIndex(id, 0); }