use of com.palantir.paxos.PaxosValue in project atlasdb by palantir.
the class PaxosLeaderElectionService method updateLearnedStateFromPeers.
/**
* Queries all other learners for unknown learned values
*
* @returns true if new state was learned, otherwise false
*/
public boolean updateLearnedStateFromPeers(Optional<PaxosValue> greatestLearned) {
final long nextToLearnSeq = greatestLearned.map(value -> value.getRound()).orElse(PaxosAcceptor.NO_LOG_ENTRY) + 1;
List<PaxosUpdate> updates = PaxosQuorumChecker.<PaxosLearner, PaxosUpdate>collectQuorumResponses(learners, new Function<PaxosLearner, PaxosUpdate>() {
@Override
@Nullable
public PaxosUpdate apply(@Nullable PaxosLearner learner) {
return new PaxosUpdate(copyOf(learner.getLearnedValuesSince(nextToLearnSeq)));
}
}, proposer.getQuorumSize(), executor, PaxosQuorumChecker.DEFAULT_REMOTE_REQUESTS_TIMEOUT_IN_SECONDS);
// learn the state accumulated from peers
boolean learned = false;
for (PaxosUpdate update : updates) {
ImmutableCollection<PaxosValue> values = update.getValues();
for (PaxosValue value : values) {
PaxosValue currentLearnedValue = knowledge.getLearnedValue(value.getRound());
if (currentLearnedValue == null) {
knowledge.learn(value.getRound(), value);
learned = true;
}
}
}
return learned;
}
use of com.palantir.paxos.PaxosValue in project atlasdb by palantir.
the class LeaderRemotingTest method testAccept.
@Test
public void testAccept() throws IOException {
PaxosProposalId id = new PaxosProposalId(123123, UUID.randomUUID().toString());
PaxosProposal paxosProposal = new PaxosProposal(id, new PaxosValue(id.getProposerUUID(), 0, new byte[] { 0, 1, 2, 4, 1 }));
PaxosAcceptor accept = AtlasDbFeignTargetFactory.createProxy(Optional.empty(), acceptor.baseUri().toString(), PaxosAcceptor.class, UserAgents.DEFAULT_USER_AGENT);
accept.accept(0, paxosProposal);
accept.getLatestSequencePreparedOrAccepted();
accept.prepare(0, id);
accept.prepare(1, id);
}
use of com.palantir.paxos.PaxosValue in project atlasdb by palantir.
the class PaxosTimestampBoundStore method storeUpperLimit.
/**
* Proposes a new timestamp limit, with sequence number 1 greater than the current agreed bound, or
* PaxosAcceptor.NO_LOG_ENTRY + 1 if nothing has been proposed or accepted yet.
*
* @param limit the new upper limit to be stored
* @throws IllegalArgumentException if trying to persist a limit smaller than the agreed limit
* @throws NotCurrentLeaderException if the timestamp limit has changed out from under us
*/
@Override
public synchronized void storeUpperLimit(long limit) throws MultipleRunningTimestampServiceError {
long newSeq = PaxosAcceptor.NO_LOG_ENTRY + 1;
if (agreedState != null) {
Preconditions.checkArgument(limit >= agreedState.getBound(), "Tried to store an upper limit %s less than the current limit %s", limit, agreedState.getBound());
newSeq = agreedState.getSeqId() + 1;
}
while (true) {
try {
proposer.propose(newSeq, PtBytes.toBytes(limit));
PaxosValue value = knowledge.getLearnedValue(newSeq);
checkAgreedBoundIsOurs(limit, newSeq, value);
long newLimit = PtBytes.toLong(value.getData());
agreedState = ImmutableSequenceAndBound.of(newSeq, newLimit);
if (newLimit < limit) {
// The bound is ours, but is not high enough.
// This is dangerous; proposing at the next sequence number is unsafe, as timestamp services
// generally assume they have the ALLOCATION_BUFFER_SIZE timestamps up to this.
// TODO (jkong): Devise a method that better preserves availability of the cluster.
log.warn("It appears we updated the timestamp limit to {}, which was less than our target {}." + " This suggests we have another timestamp service running; possibly because we" + " lost and regained leadership. For safety, we are now stopping this service.", SafeArg.of("newLimit", newLimit), SafeArg.of("target", limit));
throw new NotCurrentLeaderException(String.format("We updated the timestamp limit to %s, which was less than our target %s.", newLimit, limit));
}
return;
} catch (PaxosRoundFailureException e) {
waitForRandomBackoff(e, this::wait);
}
}
}
use of com.palantir.paxos.PaxosValue in project atlasdb by palantir.
the class LeadersTest method canCreateProxyAndLocalListOfPaxosLearners.
@Test
public void canCreateProxyAndLocalListOfPaxosLearners() {
PaxosLearner localLearner = mock(PaxosLearner.class);
PaxosValue value = mock(PaxosValue.class);
when(localLearner.getGreatestLearnedValue()).thenReturn(value);
List<PaxosLearner> paxosLearners = Leaders.createProxyAndLocalList(localLearner, REMOTE_SERVICE_ADDRESSES, Optional.empty(), PaxosLearner.class);
MatcherAssert.assertThat(paxosLearners.size(), is(REMOTE_SERVICE_ADDRESSES.size() + 1));
paxosLearners.forEach(object -> MatcherAssert.assertThat(object, not(nullValue())));
MatcherAssert.assertThat(Iterables.getLast(paxosLearners).getGreatestLearnedValue(), is(value));
verify(localLearner).getGreatestLearnedValue();
verifyNoMoreInteractions(localLearner);
}
use of com.palantir.paxos.PaxosValue in project atlasdb by palantir.
the class LeaderRemotingTest method testLearn.
@Test
public void testLearn() throws IOException {
PaxosValue value = new PaxosValue("asdfasdfsa", 0, new byte[] { 0, 1, 2 });
PaxosLearner learn = AtlasDbFeignTargetFactory.createProxy(Optional.empty(), learner.baseUri().toString(), PaxosLearner.class, UserAgents.DEFAULT_USER_AGENT);
learn.getGreatestLearnedValue();
learn.getLearnedValuesSince(0);
learn.learn(0, value);
PaxosValue val = learn.getGreatestLearnedValue();
learn.getLearnedValuesSince(0);
learn.getLearnedValue(0);
}
Aggregations