use of io.atomix.messaging.Endpoint in project atomix by atomix.
the class RaftFuzzTest method createClient.
/**
* Creates a Raft client.
*/
private RaftClient createClient() throws Exception {
NodeId nodeId = nextNodeId();
RaftClientProtocol protocol;
if (USE_NETTY) {
Endpoint endpoint = new Endpoint(InetAddress.getLocalHost(), ++port);
MessagingService messagingManager = NettyMessagingService.builder().withEndpoint(endpoint).build().start().join();
endpointMap.put(nodeId, endpoint);
protocol = new RaftClientMessagingProtocol(messagingManager, protocolSerializer, endpointMap::get);
} else {
protocol = protocolFactory.newClientProtocol(nodeId);
}
RaftClient client = RaftClient.builder().withNodeId(nodeId).withProtocol(protocol).build();
client.connect(members.stream().map(RaftMember::nodeId).collect(Collectors.toList())).join();
clients.add(client);
return client;
}
use of io.atomix.messaging.Endpoint in project atomix by atomix.
the class NettyMessagingService method getChannel.
private CompletableFuture<Channel> getChannel(Endpoint endpoint, String messageType) {
List<CompletableFuture<Channel>> channelPool = getChannelPool(endpoint);
int offset = getChannelOffset(messageType);
CompletableFuture<Channel> channelFuture = channelPool.get(offset);
if (channelFuture == null || channelFuture.isCompletedExceptionally()) {
synchronized (channelPool) {
channelFuture = channelPool.get(offset);
if (channelFuture == null || channelFuture.isCompletedExceptionally()) {
channelFuture = openChannel(endpoint);
channelPool.set(offset, channelFuture);
}
}
}
final CompletableFuture<Channel> future = new CompletableFuture<>();
final CompletableFuture<Channel> finalFuture = channelFuture;
finalFuture.whenComplete((channel, error) -> {
if (error == null) {
if (!channel.isActive()) {
final CompletableFuture<Channel> currentFuture;
synchronized (channelPool) {
currentFuture = channelPool.get(offset);
if (currentFuture == finalFuture) {
channelPool.set(offset, null);
}
}
final ClientConnection connection = clientConnections.remove(channel);
if (connection != null) {
connection.close();
}
if (currentFuture == finalFuture) {
getChannel(endpoint, messageType).whenComplete((recursiveResult, recursiveError) -> {
if (recursiveError == null) {
future.complete(recursiveResult);
} else {
future.completeExceptionally(recursiveError);
}
});
} else {
currentFuture.whenComplete((recursiveResult, recursiveError) -> {
if (recursiveError == null) {
future.complete(recursiveResult);
} else {
future.completeExceptionally(recursiveError);
}
});
}
} else {
future.complete(channel);
}
} else {
future.completeExceptionally(error);
}
});
return future;
}
use of io.atomix.messaging.Endpoint in project atomix by atomix.
the class NettyMessagingServiceTest method testSendAndReceive.
@Test
// FIXME disabled on 9/29/16 due to random failures
@Ignore
public void testSendAndReceive() {
String subject = nextSubject();
AtomicBoolean handlerInvoked = new AtomicBoolean(false);
AtomicReference<byte[]> request = new AtomicReference<>();
AtomicReference<Endpoint> sender = new AtomicReference<>();
BiFunction<Endpoint, byte[], byte[]> handler = (ep, data) -> {
handlerInvoked.set(true);
sender.set(ep);
request.set(data);
return "hello there".getBytes();
};
netty2.registerHandler(subject, handler, MoreExecutors.directExecutor());
CompletableFuture<byte[]> response = netty1.sendAndReceive(ep2, subject, "hello world".getBytes());
assertTrue(Arrays.equals("hello there".getBytes(), response.join()));
assertTrue(handlerInvoked.get());
assertTrue(Arrays.equals(request.get(), "hello world".getBytes()));
assertEquals(ep1, sender.get());
}
use of io.atomix.messaging.Endpoint in project atomix by atomix.
the class NettyMessagingServiceTest method testSendAndReceiveWithExecutor.
/*
* Supplies executors when registering a handler and calling sendAndReceive and verifies the request handling
* and response completion occurs on the expected thread.
*/
@Test
@Ignore
public void testSendAndReceiveWithExecutor() {
String subject = nextSubject();
ExecutorService completionExecutor = Executors.newSingleThreadExecutor(r -> new Thread(r, "completion-thread"));
ExecutorService handlerExecutor = Executors.newSingleThreadExecutor(r -> new Thread(r, "handler-thread"));
AtomicReference<String> handlerThreadName = new AtomicReference<>();
AtomicReference<String> completionThreadName = new AtomicReference<>();
final CountDownLatch latch = new CountDownLatch(1);
BiFunction<Endpoint, byte[], byte[]> handler = (ep, data) -> {
handlerThreadName.set(Thread.currentThread().getName());
try {
latch.await();
} catch (InterruptedException e1) {
Thread.currentThread().interrupt();
fail("InterruptedException");
}
return "hello there".getBytes();
};
netty2.registerHandler(subject, handler, handlerExecutor);
CompletableFuture<byte[]> response = netty1.sendAndReceive(ep2, subject, "hello world".getBytes(), completionExecutor);
response.whenComplete((r, e) -> {
completionThreadName.set(Thread.currentThread().getName());
});
latch.countDown();
// Verify that the message was request handling and response completion happens on the correct thread.
assertTrue(Arrays.equals("hello there".getBytes(), response.join()));
assertEquals("completion-thread", completionThreadName.get());
assertEquals("handler-thread", handlerThreadName.get());
}
use of io.atomix.messaging.Endpoint in project atomix by atomix.
the class TestMessagingService method getHandler.
/**
* Returns the given handler for the given endpoint.
*/
private BiFunction<Endpoint, byte[], CompletableFuture<byte[]>> getHandler(Endpoint endpoint, String type) {
TestMessagingService service = getService(endpoint);
if (service == null) {
return (e, p) -> Futures.exceptionalFuture(new NoRemoteHandler());
}
BiFunction<Endpoint, byte[], CompletableFuture<byte[]>> handler = service.handlers.get(checkNotNull(type));
if (handler == null) {
return (e, p) -> Futures.exceptionalFuture(new NoRemoteHandler());
}
return handler;
}
Aggregations