/** * Connects to the server. */ CompletableFuture<Void> connect(LocalConnection connection) { LocalConnection localConnection = new LocalConnection(listener.context, connections); connections.add(localConnection); connection.connect(localConnection); localConnection.connect(connection); return CompletableFuture.runAsync(() -> listener.listener.accept(localConnection), listener.context.executor()); }
HandlerHolder holder = handlers.get(request.getClass()); if (holder == null) { connection.handleResponseError(requestId, new TransportException("no handler registered")); return; handler.handle(request).whenComplete((response, error) -> { if (!open || !connection.open) { connection.handleResponseError(requestId, new IllegalStateException("connection closed")); } else if (error == null) { connection.handleResponseOk(requestId, response); } else { connection.handleResponseError(requestId, error); connection.handleResponseError(requestId, new IllegalStateException("connection closed")); connection.handleResponseError(requestId, new IllegalStateException("connection closed"));
@Override public synchronized CompletableFuture<Void> close() { if (address == null) return CompletableFuture.completedFuture(null); CompletableFuture<Void> future = new CompletableFuture<>(); registry.unregister(address); address = null; listener = null; ThreadContext context = ThreadContext.currentContextOrThrow(); CompletableFuture<?>[] futures = new CompletableFuture[connections.size()]; int i = 0; for (LocalConnection connection : connections) { futures[i++] = connection.close(); } CompletableFuture.allOf(futures).thenRunAsync(() -> future.complete(null), context.executor()); return future; }
/** * Sends a request. */ private void sendRequest(Object request, ContextualFuture future) { if (open && connection.open) { long requestId = ++this.requestId; futures.put(requestId, future); connection.handleRequest(requestId, request); } else { future.context.executor().execute(() -> future.completeExceptionally(new IllegalStateException("connection closed"))); } if (request instanceof ReferenceCounted) { ((ReferenceCounted<?>) request).release(); } }
@Override public <T, U> CompletableFuture<U> send(T request) { if (!open || !connection.open) return Futures.exceptionalFuture(new IllegalStateException("connection closed")); Assert.notNull(request, "request"); ContextualFuture<U> future = new ContextualFuture<>(ThreadContext.currentContextOrThrow()); this.context.execute(() -> sendRequest(request, future)); return future; }
@Override public CompletableFuture<Connection> connect(Address address) { Assert.notNull(address, "address"); ThreadContext context = getContext(); LocalServer server = registry.get(address); if (server == null) { return Futures.exceptionalFutureAsync(new TransportException("failed to connect"), context.executor()); } LocalConnection connection = new LocalConnection(context, connections); connections.add(connection); CompletableFuture<Connection> future = new CompletableFuture<>(); server.connect(connection).whenCompleteAsync((result, error) -> { if (error == null) { future.complete(connection); } else { future.completeExceptionally(error); } }, context.executor()); return future; }
@Override public CompletableFuture<Void> close() { ComposableFuture<Void> future = new ComposableFuture<>(); ThreadContext context = getContext(); CompletableFuture<?>[] futures = new CompletableFuture[connections.size()]; int i = 0; for (LocalConnection connection : connections) { futures[i++] = connection.close(); } CompletableFuture.allOf(futures).whenCompleteAsync(future, context.executor()); return future; }