use of io.atomix.cluster.MemberId in project atomix by atomix.
the class AntiEntropyMapDelegate method handleUpdateRequests.
private void handleUpdateRequests(UpdateRequest<String> request) {
final Set<String> keys = request.keys();
final MemberId sender = request.sender();
final List<MemberId> peers = ImmutableList.of(sender);
keys.forEach(key -> queueUpdate(new UpdateEntry(key, items.get(key)), peers));
}
use of io.atomix.cluster.MemberId in project atomix by atomix.
the class AntiEntropyMapDelegate method requestBootstrapFromPeers.
/**
* Requests all updates from each peer in the provided list of peers.
* <p>
* The returned future will be completed once at least one peer bootstraps this map or bootstrap requests to all peers
* fail.
*
* @param peers the list of peers from which to request updates
* @return a future to be completed once updates have been received from at least one peer
*/
private CompletableFuture<Void> requestBootstrapFromPeers(List<MemberId> peers) {
if (peers.isEmpty()) {
return CompletableFuture.completedFuture(null);
}
CompletableFuture<Void> future = new CompletableFuture<>();
final int totalPeers = peers.size();
AtomicBoolean successful = new AtomicBoolean();
AtomicInteger totalCount = new AtomicInteger();
AtomicReference<Throwable> lastError = new AtomicReference<>();
// successful bootstrap response, the future will be completed with the last exception.
for (MemberId peer : peers) {
requestBootstrapFromPeer(peer).whenComplete((result, error) -> {
if (error == null) {
if (successful.compareAndSet(false, true)) {
future.complete(null);
} else if (totalCount.incrementAndGet() == totalPeers) {
Throwable e = lastError.get();
if (e != null) {
future.completeExceptionally(e);
}
}
} else {
if (!successful.get() && totalCount.incrementAndGet() == totalPeers) {
future.completeExceptionally(error);
} else {
lastError.set(error);
}
}
});
}
return future;
}
use of io.atomix.cluster.MemberId in project atomix by atomix.
the class DistributedLogTest method createClient.
/**
* Creates a Raft client.
*/
private DistributedLogSessionClient createClient() throws Throwable {
MemberId memberId = nextMemberId();
DistributedLogSessionClient client = DistributedLogSessionClient.builder().withClientName("test").withPartitionId(PartitionId.from("test", 1)).withMembershipService(new TestClusterMembershipService(memberId, nodes)).withSessionIdProvider(() -> CompletableFuture.completedFuture(nextSessionId())).withPrimaryElection(election).withProtocol(protocolFactory.newClientProtocol(memberId)).build();
clients.add(client);
return client;
}
use of io.atomix.cluster.MemberId in project atomix by atomix.
the class DistributedLogTest method clearTests.
@Before
@After
public void clearTests() throws Exception {
Futures.allOf(servers.stream().map(s -> s.stop().exceptionally(v -> null)).collect(Collectors.toList())).get(30, TimeUnit.SECONDS);
Futures.allOf(clients.stream().map(c -> c.close().exceptionally(v -> null)).collect(Collectors.toList())).get(30, TimeUnit.SECONDS);
Path directory = Paths.get("target/test-logs/");
if (Files.exists(directory)) {
Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
}
nodes = new ArrayList<>();
memberId = 0;
sessionId = 0;
clients = new ArrayList<>();
servers = new ArrayList<>();
protocolFactory = new TestLogProtocolFactory();
election = new TestPrimaryElection(PartitionId.from("test", 1));
}
use of io.atomix.cluster.MemberId in project atomix by atomix.
the class SynchronousReplicator method replicate.
@Override
public CompletableFuture<Void> replicate(BackupOperation operation) {
if (context.followers().isEmpty()) {
context.setCommitIndex(operation.index());
return CompletableFuture.completedFuture(null);
}
CompletableFuture<Void> future = new CompletableFuture<>();
futures.put(operation.index(), future);
for (MemberId backup : context.followers()) {
queues.computeIfAbsent(backup, BackupQueue::new).add(operation);
}
return future;
}
Aggregations