List of usage examples for com.google.common.util.concurrent SettableFuture isDone
@Override public boolean isDone()
From source file:com.metamx.http.client.NettyHttpClient.java
@Override public <Intermediate, Final> ListenableFuture<Final> go(final Request request, final HttpResponseHandler<Intermediate, Final> handler, final Duration requestReadTimeout) { final HttpMethod method = request.getMethod(); final URL url = request.getUrl(); final Multimap<String, String> headers = request.getHeaders(); final String requestDesc = String.format("%s %s", method, url); if (log.isDebugEnabled()) { log.debug("[%s] starting", requestDesc); }// ww w . ja v a2s. c o m // Block while acquiring a channel from the pool, then complete the request asynchronously. final Channel channel; final String hostKey = getPoolKey(url); final ResourceContainer<ChannelFuture> channelResourceContainer = pool.take(hostKey); final ChannelFuture channelFuture = channelResourceContainer.get().awaitUninterruptibly(); if (!channelFuture.isSuccess()) { channelResourceContainer.returnResource(); // Some other poor sap will have to deal with it... return Futures.immediateFailedFuture( new ChannelException("Faulty channel in resource pool", channelFuture.getCause())); } else { channel = channelFuture.getChannel(); } final String urlFile = Strings.nullToEmpty(url.getFile()); final HttpRequest httpRequest = new DefaultHttpRequest(HttpVersion.HTTP_1_1, method, urlFile.isEmpty() ? "/" : urlFile); if (!headers.containsKey(HttpHeaders.Names.HOST)) { httpRequest.headers().add(HttpHeaders.Names.HOST, getHost(url)); } httpRequest.headers().set(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP); for (Map.Entry<String, Collection<String>> entry : headers.asMap().entrySet()) { String key = entry.getKey(); for (String obj : entry.getValue()) { httpRequest.headers().add(key, obj); } } if (request.hasContent()) { httpRequest.setContent(request.getContent()); } final long readTimeout = getReadTimeout(requestReadTimeout); final SettableFuture<Final> retVal = SettableFuture.create(); if (readTimeout > 0) { channel.getPipeline().addLast(READ_TIMEOUT_HANDLER_NAME, new ReadTimeoutHandler(timer, readTimeout, TimeUnit.MILLISECONDS)); } channel.getPipeline().addLast(LAST_HANDLER_NAME, new SimpleChannelUpstreamHandler() { private volatile ClientResponse<Intermediate> response = null; @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { if (log.isDebugEnabled()) { log.debug("[%s] messageReceived: %s", requestDesc, e.getMessage()); } try { Object msg = e.getMessage(); if (msg instanceof HttpResponse) { HttpResponse httpResponse = (HttpResponse) msg; if (log.isDebugEnabled()) { log.debug("[%s] Got response: %s", requestDesc, httpResponse.getStatus()); } response = handler.handleResponse(httpResponse); if (response.isFinished()) { retVal.set((Final) response.getObj()); } if (!httpResponse.isChunked()) { finishRequest(); } } else if (msg instanceof HttpChunk) { HttpChunk httpChunk = (HttpChunk) msg; if (log.isDebugEnabled()) { log.debug("[%s] Got chunk: %sB, last=%s", requestDesc, httpChunk.getContent().readableBytes(), httpChunk.isLast()); } if (httpChunk.isLast()) { finishRequest(); } else { response = handler.handleChunk(response, httpChunk); if (response.isFinished() && !retVal.isDone()) { retVal.set((Final) response.getObj()); } } } else { throw new IllegalStateException(String.format("Unknown message type[%s]", msg.getClass())); } } catch (Exception ex) { log.warn(ex, "[%s] Exception thrown while processing message, closing channel.", requestDesc); if (!retVal.isDone()) { retVal.set(null); } channel.close(); channelResourceContainer.returnResource(); throw ex; } } private void finishRequest() { ClientResponse<Final> finalResponse = handler.done(response); if (!finalResponse.isFinished()) { throw new IllegalStateException( String.format("[%s] Didn't get a completed ClientResponse Object from [%s]", requestDesc, handler.getClass())); } if (!retVal.isDone()) { retVal.set(finalResponse.getObj()); } removeHandlers(); channelResourceContainer.returnResource(); } @Override public void exceptionCaught(ChannelHandlerContext context, ExceptionEvent event) throws Exception { if (log.isDebugEnabled()) { final Throwable cause = event.getCause(); if (cause == null) { log.debug("[%s] Caught exception", requestDesc); } else { log.debug(cause, "[%s] Caught exception", requestDesc); } } retVal.setException(event.getCause()); // response is non-null if we received initial chunk and then exception occurs if (response != null) { handler.exceptionCaught(response, event.getCause()); } removeHandlers(); try { channel.close(); } catch (Exception e) { // ignore } finally { channelResourceContainer.returnResource(); } context.sendUpstream(event); } @Override public void channelDisconnected(ChannelHandlerContext context, ChannelStateEvent event) throws Exception { if (log.isDebugEnabled()) { log.debug("[%s] Channel disconnected", requestDesc); } // response is non-null if we received initial chunk and then exception occurs if (response != null) { handler.exceptionCaught(response, new ChannelException("Channel disconnected")); } channel.close(); channelResourceContainer.returnResource(); if (!retVal.isDone()) { log.warn("[%s] Channel disconnected before response complete", requestDesc); retVal.setException(new ChannelException("Channel disconnected")); } context.sendUpstream(event); } private void removeHandlers() { if (readTimeout > 0) { channel.getPipeline().remove(READ_TIMEOUT_HANDLER_NAME); } channel.getPipeline().remove(LAST_HANDLER_NAME); } }); channel.write(httpRequest).addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (!future.isSuccess()) { channel.close(); channelResourceContainer.returnResource(); if (!retVal.isDone()) { retVal.setException(new ChannelException( String.format("[%s] Failed to write request to channel", requestDesc), future.getCause())); } } } }); return retVal; }
From source file:org.apache.qpid.server.model.AbstractConfiguredObject.java
private ListenableFuture<Void> doAttainState(final AbstractConfiguredObjectExceptionHandler exceptionHandler) { final List<ListenableFuture<Void>> childStateFutures = new ArrayList<>(); applyToChildren(new Action<ConfiguredObject<?>>() { @Override//from ww w . j a v a 2 s .c o m public void performAction(final ConfiguredObject<?> child) { if (child instanceof AbstractConfiguredObject) { AbstractConfiguredObject<?> abstractConfiguredChild = (AbstractConfiguredObject<?>) child; if (abstractConfiguredChild._dynamicState.get().getDynamicState() == DynamicState.OPENED) { final AbstractConfiguredObject configuredObject = abstractConfiguredChild; childStateFutures.add(configuredObject.doAttainState(exceptionHandler)); } } else if (child instanceof AbstractConfiguredObjectProxy && ((AbstractConfiguredObjectProxy) child).getDynamicState() == DynamicState.OPENED) { final AbstractConfiguredObjectProxy configuredObject = (AbstractConfiguredObjectProxy) child; childStateFutures.add(configuredObject.doAttainState(exceptionHandler)); } } }); ListenableFuture<List<Void>> combinedChildStateFuture = Futures.allAsList(childStateFutures); final SettableFuture<Void> returnVal = SettableFuture.create(); addFutureCallback(combinedChildStateFuture, new FutureCallback<List<Void>>() { @Override public void onSuccess(final List<Void> result) { try { addFutureCallback(attainState(), new FutureCallback<Void>() { @Override public void onSuccess(final Void result1) { returnVal.set(null); } @Override public void onFailure(final Throwable t) { try { if (t instanceof RuntimeException) { try { exceptionHandler.handleException((RuntimeException) t, AbstractConfiguredObject.this); returnVal.set(null); } catch (RuntimeException r) { returnVal.setException(r); } } } finally { if (!returnVal.isDone()) { returnVal.setException(t); } } } }, getTaskExecutor()); } catch (RuntimeException e) { try { exceptionHandler.handleException(e, AbstractConfiguredObject.this); returnVal.set(null); } catch (Throwable t) { returnVal.setException(t); } } } @Override public void onFailure(final Throwable t) { // One or more children failed to attain state but the error could not be handled by the handler returnVal.setException(t); } }, getTaskExecutor()); return returnVal; }
From source file:org.apache.druid.java.util.http.client.NettyHttpClient.java
@Override public <Intermediate, Final> ListenableFuture<Final> go(final Request request, final HttpResponseHandler<Intermediate, Final> handler, final Duration requestReadTimeout) { final HttpMethod method = request.getMethod(); final URL url = request.getUrl(); final Multimap<String, String> headers = request.getHeaders(); final String requestDesc = StringUtils.format("%s %s", method, url); if (log.isDebugEnabled()) { log.debug("[%s] starting", requestDesc); }/*from ww w. j a va 2 s .c o m*/ // Block while acquiring a channel from the pool, then complete the request asynchronously. final Channel channel; final String hostKey = getPoolKey(url); final ResourceContainer<ChannelFuture> channelResourceContainer = pool.take(hostKey); final ChannelFuture channelFuture = channelResourceContainer.get().awaitUninterruptibly(); if (!channelFuture.isSuccess()) { channelResourceContainer.returnResource(); // Some other poor sap will have to deal with it... return Futures.immediateFailedFuture( new ChannelException("Faulty channel in resource pool", channelFuture.getCause())); } else { channel = channelFuture.getChannel(); // In case we get a channel that never had its readability turned back on. channel.setReadable(true); } final String urlFile = StringUtils.nullToEmptyNonDruidDataString(url.getFile()); final HttpRequest httpRequest = new DefaultHttpRequest(HttpVersion.HTTP_1_1, method, urlFile.isEmpty() ? "/" : urlFile); if (!headers.containsKey(HttpHeaders.Names.HOST)) { httpRequest.headers().add(HttpHeaders.Names.HOST, getHost(url)); } // If Accept-Encoding is set in the Request, use that. Otherwise use the default from "compressionCodec". if (!headers.containsKey(HttpHeaders.Names.ACCEPT_ENCODING)) { httpRequest.headers().set(HttpHeaders.Names.ACCEPT_ENCODING, compressionCodec.getEncodingString()); } for (Map.Entry<String, Collection<String>> entry : headers.asMap().entrySet()) { String key = entry.getKey(); for (String obj : entry.getValue()) { httpRequest.headers().add(key, obj); } } if (request.hasContent()) { httpRequest.setContent(request.getContent()); } final long readTimeout = getReadTimeout(requestReadTimeout); final SettableFuture<Final> retVal = SettableFuture.create(); if (readTimeout > 0) { channel.getPipeline().addLast(READ_TIMEOUT_HANDLER_NAME, new ReadTimeoutHandler(timer, readTimeout, TimeUnit.MILLISECONDS)); } channel.getPipeline().addLast(LAST_HANDLER_NAME, new SimpleChannelUpstreamHandler() { private volatile ClientResponse<Intermediate> response = null; // Chunk number most recently assigned. private long currentChunkNum = 0; // Suspend and resume watermarks (respectively: last chunk number that triggered a suspend, and that was // provided to the TrafficCop's resume method). Synchronized access since they are not always accessed // from an I/O thread. (TrafficCops can be called from any thread.) private final Object watermarkLock = new Object(); private long suspendWatermark = -1; private long resumeWatermark = -1; @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { if (log.isDebugEnabled()) { log.debug("[%s] messageReceived: %s", requestDesc, e.getMessage()); } try { Object msg = e.getMessage(); if (msg instanceof HttpResponse) { HttpResponse httpResponse = (HttpResponse) msg; if (log.isDebugEnabled()) { log.debug("[%s] Got response: %s", requestDesc, httpResponse.getStatus()); } HttpResponseHandler.TrafficCop trafficCop = resumeChunkNum -> { synchronized (watermarkLock) { resumeWatermark = Math.max(resumeWatermark, resumeChunkNum); if (suspendWatermark >= 0 && resumeWatermark >= suspendWatermark) { suspendWatermark = -1; channel.setReadable(true); long backPressureDuration = System.nanoTime() - backPressureStartTimeNs; log.debug("[%s] Resumed reads from channel (chunkNum = %,d).", requestDesc, resumeChunkNum); return backPressureDuration; } } return 0; //If we didn't resume, don't know if backpressure was happening }; response = handler.handleResponse(httpResponse, trafficCop); if (response.isFinished()) { retVal.set((Final) response.getObj()); } assert currentChunkNum == 0; possiblySuspendReads(response); if (!httpResponse.isChunked()) { finishRequest(); } } else if (msg instanceof HttpChunk) { HttpChunk httpChunk = (HttpChunk) msg; if (log.isDebugEnabled()) { log.debug("[%s] Got chunk: %sB, last=%s", requestDesc, httpChunk.getContent().readableBytes(), httpChunk.isLast()); } if (httpChunk.isLast()) { finishRequest(); } else { response = handler.handleChunk(response, httpChunk, ++currentChunkNum); if (response.isFinished() && !retVal.isDone()) { retVal.set((Final) response.getObj()); } possiblySuspendReads(response); } } else { throw new IllegalStateException( StringUtils.format("Unknown message type[%s]", msg.getClass())); } } catch (Exception ex) { log.warn(ex, "[%s] Exception thrown while processing message, closing channel.", requestDesc); if (!retVal.isDone()) { retVal.set(null); } channel.close(); channelResourceContainer.returnResource(); throw ex; } } private void possiblySuspendReads(ClientResponse<?> response) { if (!response.isContinueReading()) { synchronized (watermarkLock) { suspendWatermark = Math.max(suspendWatermark, currentChunkNum); if (suspendWatermark > resumeWatermark) { channel.setReadable(false); backPressureStartTimeNs = System.nanoTime(); log.debug("[%s] Suspended reads from channel (chunkNum = %,d).", requestDesc, currentChunkNum); } } } } private void finishRequest() { ClientResponse<Final> finalResponse = handler.done(response); if (!finalResponse.isFinished() || !finalResponse.isContinueReading()) { throw new ISE( "[%s] Didn't get a completed ClientResponse Object from [%s] (finished = %s, continueReading = %s)", requestDesc, handler.getClass(), finalResponse.isFinished(), finalResponse.isContinueReading()); } if (!retVal.isDone()) { retVal.set(finalResponse.getObj()); } removeHandlers(); channel.setReadable(true); channelResourceContainer.returnResource(); } @Override public void exceptionCaught(ChannelHandlerContext context, ExceptionEvent event) { if (log.isDebugEnabled()) { final Throwable cause = event.getCause(); if (cause == null) { log.debug("[%s] Caught exception", requestDesc); } else { log.debug(cause, "[%s] Caught exception", requestDesc); } } retVal.setException(event.getCause()); // response is non-null if we received initial chunk and then exception occurs if (response != null) { handler.exceptionCaught(response, event.getCause()); } try { if (channel.isOpen()) { channel.close(); } } catch (Exception e) { log.warn(e, "Error while closing channel"); } finally { channelResourceContainer.returnResource(); } } @Override public void channelDisconnected(ChannelHandlerContext context, ChannelStateEvent event) { if (log.isDebugEnabled()) { log.debug("[%s] Channel disconnected", requestDesc); } // response is non-null if we received initial chunk and then exception occurs if (response != null) { handler.exceptionCaught(response, new ChannelException("Channel disconnected")); } channel.close(); channelResourceContainer.returnResource(); if (!retVal.isDone()) { log.warn("[%s] Channel disconnected before response complete", requestDesc); retVal.setException(new ChannelException("Channel disconnected")); } } private void removeHandlers() { if (readTimeout > 0) { channel.getPipeline().remove(READ_TIMEOUT_HANDLER_NAME); } channel.getPipeline().remove(LAST_HANDLER_NAME); } }); channel.write(httpRequest).addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) { if (!future.isSuccess()) { channel.close(); channelResourceContainer.returnResource(); if (!retVal.isDone()) { retVal.setException(new ChannelException( StringUtils.format("[%s] Failed to write request to channel", requestDesc), future.getCause())); } } } }); return retVal; }