List of usage examples for io.netty.util.concurrent Future cause
Throwable cause();
From source file:com.linecorp.armeria.client.circuitbreaker.CircuitBreakerRemoteInvokerTest.java
License:Apache License
@Test public void testExceptionFilter() throws Exception { FakeTicker ticker = new FakeTicker(); int minimumRequestThreshold = 2; Duration circuitOpenWindow = Duration.ofSeconds(60); Duration counterSlidingWindow = Duration.ofSeconds(180); Duration counterUpdateInterval = Duration.ofMillis(1); Future<Object> failedFuture = failedFuture(); // a filter that ignores all exception ExceptionFilter exceptionFilter = (cause) -> false; CircuitBreaker circuitBreaker = new CircuitBreakerBuilder(remoteServiceName) .minimumRequestThreshold(minimumRequestThreshold).circuitOpenWindow(circuitOpenWindow) .counterSlidingWindow(counterSlidingWindow).counterUpdateInterval(counterUpdateInterval) .exceptionFilter(exceptionFilter).ticker(ticker).build(); RemoteInvoker remoteInvoker = mock(RemoteInvoker.class); // return failed future when(remoteInvoker.invoke(any(), any(), any(), any(), any(), any())).thenReturn(failedFuture); CircuitBreakerMapping mapping = (eventLoop1, uri, options1, codec1, method, args1) -> circuitBreaker; CircuitBreakerRemoteInvoker stub = new CircuitBreakerRemoteInvoker(remoteInvoker, mapping); // CLOSED// w ww . j av a 2s . c om for (int i = 0; i < minimumRequestThreshold + 1; i++) { Future<Object> future = stub.invoke(eventLoop, uri, options, codec, methodA(), args); // The future is `failedFuture` itself assertThat(future.isSuccess(), is(false)); // This is not a CircuitBreakerException assertThat(future.cause(), is(not(instanceOf(FailFastException.class)))); ticker.advance(Duration.ofMillis(1).toNanos()); } // OPEN Future<Object> future1 = stub.invoke(eventLoop, uri, options, codec, methodA(), args); // The circuit is still CLOSED assertThat(future1.isSuccess(), is(false)); assertThat(future1.cause(), is(not(instanceOf(FailFastException.class)))); }
From source file:com.linecorp.armeria.client.endpoint.dns.DnsEndpointGroup.java
License:Apache License
private void sendQueries() { if (stopped) { return;/*from ww w . java2 s . c o m*/ } final Future<List<DnsRecord>> future; final int numQuestions = questions.size(); if (numQuestions == 1) { // Simple case of single query final DnsQuestion question = questions.get(0); logger.debug("{} Sending a DNS query", logPrefix); future = resolver.resolveAll(question); } else { // Multiple queries logger.debug("{} Sending DNS queries", logPrefix); @SuppressWarnings("unchecked") final Promise<List<DnsRecord>> aggregatedPromise = eventLoop.newPromise(); final FutureListener<List<DnsRecord>> listener = new FutureListener<List<DnsRecord>>() { private final List<DnsRecord> records = new ArrayList<>(); private int remaining = numQuestions; @Nullable private List<Throwable> causes; @Override public void operationComplete(Future<List<DnsRecord>> future) throws Exception { if (future.isSuccess()) { final List<DnsRecord> records = future.getNow(); this.records.addAll(records); } else { if (causes == null) { causes = new ArrayList<>(numQuestions); } causes.add(future.cause()); } if (--remaining == 0) { if (!records.isEmpty()) { aggregatedPromise.setSuccess(records); } else { final Throwable aggregatedCause; if (causes == null) { aggregatedCause = new EndpointGroupException("empty result returned by DNS server"); } else { aggregatedCause = new EndpointGroupException("failed to receive DNS records"); for (Throwable c : causes) { aggregatedCause.addSuppressed(c); } } aggregatedPromise.setFailure(aggregatedCause); } } } }; questions.forEach(q -> resolver.resolveAll(q).addListener(listener)); future = aggregatedPromise; } attemptsSoFar++; future.addListener(this::onDnsRecords); }
From source file:com.linecorp.armeria.client.endpoint.dns.DnsEndpointGroup.java
License:Apache License
private void onDnsRecords(Future<? super List<DnsRecord>> future) { if (stopped) { if (future.isSuccess()) { @SuppressWarnings("unchecked") final List<DnsRecord> result = (List<DnsRecord>) future.getNow(); result.forEach(ReferenceCountUtil::safeRelease); }/*w w w . j ava 2s .com*/ return; } if (!future.isSuccess()) { // Failed. Try again with the delay given by Backoff. final long delayMillis = backoff.nextDelayMillis(attemptsSoFar); logger.warn("{} DNS query failed; retrying in {} ms (attempts so far: {}):", logPrefix, delayMillis, attemptsSoFar, future.cause()); scheduledFuture = eventLoop.schedule(this::sendQueries, delayMillis, TimeUnit.MILLISECONDS); return; } // Reset the counter so that Backoff is reset. attemptsSoFar = 0; @SuppressWarnings("unchecked") final List<DnsRecord> records = (List<DnsRecord>) future.getNow(); final long serverTtl = records.stream().mapToLong(DnsRecord::timeToLive).min().orElse(minTtl); final int effectiveTtl = (int) Math.max(Math.min(serverTtl, maxTtl), minTtl); try { setEndpoints(onDnsRecords(records, effectiveTtl)); } catch (Throwable t) { logger.warn("{} Failed to process the DNS query result: {}", logPrefix, records, t); } finally { records.forEach(ReferenceCountUtil::safeRelease); scheduledFuture = eventLoop.schedule(this::sendQueries, effectiveTtl, TimeUnit.SECONDS); } }
From source file:com.linecorp.armeria.client.http.HttpClientDelegate.java
License:Apache License
@Override public HttpResponse execute(ClientRequestContext ctx, HttpRequest req) throws Exception { final Endpoint endpoint = ctx.endpoint().resolve().withDefaultPort(ctx.sessionProtocol().defaultPort()); autoFillHeaders(ctx, endpoint, req); final PoolKey poolKey = new PoolKey(InetSocketAddress.createUnresolved(endpoint.host(), endpoint.port()), ctx.sessionProtocol());//from w w w .java 2s .c o m final EventLoop eventLoop = ctx.eventLoop(); final Future<Channel> channelFuture = pool(eventLoop).acquire(poolKey); final DecodedHttpResponse res = new DecodedHttpResponse(eventLoop); if (channelFuture.isDone()) { if (channelFuture.isSuccess()) { Channel ch = channelFuture.getNow(); invoke0(ch, ctx, req, res, poolKey); } else { res.close(channelFuture.cause()); } } else { channelFuture.addListener((Future<Channel> future) -> { if (future.isSuccess()) { Channel ch = future.getNow(); invoke0(ch, ctx, req, res, poolKey); } else { res.close(channelFuture.cause()); } }); } return res; }
From source file:com.linecorp.armeria.client.HttpClientDelegate.java
License:Apache License
@Override public HttpResponse execute(ClientRequestContext ctx, HttpRequest req) throws Exception { final Endpoint endpoint = ctx.endpoint().resolve(ctx).withDefaultPort(ctx.sessionProtocol().defaultPort()); autoFillHeaders(ctx, endpoint, req); if (!sanitizePath(req)) { req.abort();/*from w w w .j av a2s. com*/ return HttpResponse.ofFailure(new IllegalArgumentException("invalid path: " + req.path())); } final EventLoop eventLoop = ctx.eventLoop(); final PoolKey poolKey = new PoolKey(endpoint.host(), endpoint.ipAddr(), endpoint.port(), ctx.sessionProtocol()); final Future<Channel> channelFuture = factory.pool(eventLoop).acquire(poolKey); final DecodedHttpResponse res = new DecodedHttpResponse(eventLoop); if (channelFuture.isDone()) { if (channelFuture.isSuccess()) { final Channel ch = channelFuture.getNow(); invoke0(ch, ctx, req, res, poolKey); } else { res.close(channelFuture.cause()); } } else { channelFuture.addListener((Future<Channel> future) -> { if (future.isSuccess()) { final Channel ch = future.getNow(); invoke0(ch, ctx, req, res, poolKey); } else { res.close(channelFuture.cause()); } }); } return res; }
From source file:com.linecorp.armeria.client.HttpRemoteInvoker.java
License:Apache License
@Override public <T> Future<T> invoke(EventLoop eventLoop, URI uri, ClientOptions options, ClientCodec codec, Method method, Object[] args) throws Exception { requireNonNull(uri, "uri"); requireNonNull(options, "options"); requireNonNull(codec, "codec"); requireNonNull(method, "method"); final Scheme scheme = Scheme.parse(uri.getScheme()); final SessionProtocol sessionProtocol = validateSessionProtocol(scheme.sessionProtocol()); final InetSocketAddress remoteAddress = convertToSocketAddress(uri, sessionProtocol.isTls()); final PoolKey poolKey = new PoolKey(remoteAddress, sessionProtocol); final Future<Channel> channelFuture = pool(eventLoop).acquire(poolKey); final Promise<T> resultPromise = eventLoop.newPromise(); codec.prepareRequest(method, args, resultPromise); if (channelFuture.isSuccess()) { Channel ch = channelFuture.getNow(); invoke0(codec, ch, method, args, options, resultPromise, poolKey); } else {/*from w w w . j a va 2 s. c o m*/ channelFuture.addListener((Future<Channel> future) -> { if (future.isSuccess()) { Channel ch = future.getNow(); invoke0(codec, ch, method, args, options, resultPromise, poolKey); } else { resultPromise.setFailure(channelFuture.cause()); } }); } return resultPromise; }
From source file:com.linecorp.armeria.client.HttpRemoteInvoker.java
License:Apache License
static <T> void invoke0(ClientCodec codec, Channel channel, Method method, Object[] args, ClientOptions options, Promise<T> resultPromise, PoolKey poolKey) { final HttpSession session = HttpSessionHandler.get(channel); final SessionProtocol sessionProtocol = session.protocol(); if (sessionProtocol == null) { resultPromise.setFailure(ClosedSessionException.INSTANCE); return;/* w ww .j a v a2 s.c o m*/ } final EncodeResult encodeResult = codec.encodeRequest(channel, sessionProtocol, method, args); if (encodeResult.isSuccess()) { ServiceInvocationContext ctx = encodeResult.invocationContext(); Promise<FullHttpResponse> responsePromise = channel.eventLoop().newPromise(); final Invocation invocation = new Invocation(ctx, options, responsePromise, encodeResult.content()); //write request final ChannelFuture writeFuture = writeRequest(channel, invocation, ctx, options); writeFuture.addListener(fut -> { if (!fut.isSuccess()) { ctx.rejectPromise(responsePromise, fut.cause()); } else { long responseTimeoutMillis = options.responseTimeoutPolicy().timeout(ctx); scheduleTimeout(channel, responsePromise, responseTimeoutMillis, false); } }); //handle response if (responsePromise.isSuccess()) { decodeResult(codec, resultPromise, ctx, responsePromise.getNow()); } else { responsePromise.addListener((Future<FullHttpResponse> future) -> { if (future.isSuccess()) { decodeResult(codec, resultPromise, ctx, responsePromise.getNow()); } else { ctx.rejectPromise(resultPromise, future.cause()); } }); } } else { final Throwable cause = encodeResult.cause(); if (!resultPromise.tryFailure(cause)) { logger.warn("Failed to reject an invocation promise ({}) with {}", resultPromise, cause, cause); } } if (!session.onRequestSent()) { // Can't send a request via the current session anymore; do not return the channel to the pool. return; } // Return the channel to the pool. final KeyedChannelPool<PoolKey> pool = KeyedChannelPool.findPool(channel); if (sessionProtocol.isMultiplex()) { pool.release(poolKey, channel); } else { resultPromise.addListener(fut -> pool.release(poolKey, channel)); } }
From source file:com.linecorp.armeria.client.pool.DefaultKeyedChannelPool.java
License:Apache License
private void notifyConnect(K key, Future<Channel> future, Promise<Channel> promise) { assert future.isDone(); try {//from w w w . j a va 2s . co m if (future.isSuccess()) { Channel channel = future.getNow(); channel.attr(KeyedChannelPoolUtil.POOL).set(this); channelPoolHandler.channelCreated(key, channel); channel.closeFuture().addListener(f -> channelPoolHandler.channelClosed(key, channel)); promise.setSuccess(channel); } else { promise.setFailure(future.cause()); } } catch (Exception e) { promise.setFailure(e); } }
From source file:com.linecorp.armeria.client.tracing.TracingRemoteInvoker.java
License:Apache License
/** * Returns client side annotations that should be added to span. */// w w w. j a v a2 s . c o m @SuppressWarnings("UnusedParameters") protected <T> List<KeyValueAnnotation> annotations(URI uri, ClientOptions options, ClientCodec codec, Method method, Object[] args, @Nullable Future<? super T> result) { final KeyValueAnnotation clientUriAnnotation = KeyValueAnnotation.create("client.uri", uri.toString() + '#' + method.getName()); if (result == null || !result.isDone()) { return Collections.singletonList(clientUriAnnotation); } final List<KeyValueAnnotation> annotations = new ArrayList<>(3); annotations.add(clientUriAnnotation); final String clientResultText = result.isSuccess() ? "success" : "failure"; annotations.add(KeyValueAnnotation.create("client.result", clientResultText)); if (result.cause() != null) { annotations.add(KeyValueAnnotation.create("client.cause", result.cause().toString())); } return annotations; }
From source file:com.linecorp.armeria.server.tracing.TracingServiceInvocationHandler.java
License:Apache License
/** * Returns server side annotations that should be added to span. *//*from w w w . j av a 2 s .c o m*/ protected <T> List<KeyValueAnnotation> annotations(ServiceInvocationContext ctx, Future<? super T> result) { final List<KeyValueAnnotation> annotations = new ArrayList<>(5); final StringBuilder uriBuilder = new StringBuilder(); uriBuilder.append(ctx.scheme() != null ? ctx.scheme().uriText() : "unknown"); uriBuilder.append("://"); uriBuilder.append(ctx.host() != null ? ctx.host() : "<unknown-host>"); uriBuilder.append(ctx.path() != null ? ctx.path() : "/<unknown-path>"); if (ctx.method() != null) { uriBuilder.append('#'); uriBuilder.append(ctx.method()); } annotations.add(KeyValueAnnotation.create("server.uri", uriBuilder.toString())); if (ctx.remoteAddress() != null) { annotations.add(KeyValueAnnotation.create("server.remote", ctx.remoteAddress().toString())); } if (ctx.localAddress() != null) { annotations.add(KeyValueAnnotation.create("server.local", ctx.localAddress().toString())); } if (result != null && result.isDone()) { final String resultText = result.isSuccess() ? "success" : "failure"; annotations.add(KeyValueAnnotation.create("server.result", resultText)); if (result.cause() != null) { annotations.add(KeyValueAnnotation.create("server.cause", result.cause().toString())); } } return annotations; }