com.ning.http.client.providers.apache.ApacheResponseFuture Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of async-http-client Show documentation
Show all versions of async-http-client Show documentation
Async Http Client library purpose is to allow Java applications to easily execute HTTP requests and
asynchronously process the HTTP responses.
The newest version!
/*
* Copyright (c) 2010-2012 Sonatype, Inc. All rights reserved.
*
* This program is licensed to you under the Apache License Version 2.0,
* and you may not use this file except in compliance with the Apache License Version 2.0.
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the Apache License Version 2.0 is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
*/
package com.ning.http.client.providers.apache;
import static com.ning.http.util.DateUtils.millisTime;
import com.ning.http.client.AsyncHandler;
import com.ning.http.client.Request;
import com.ning.http.client.listenable.AbstractListenableFuture;
import org.apache.commons.httpclient.HttpMethodBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
public class ApacheResponseFuture extends AbstractListenableFuture {
private final static Logger logger = LoggerFactory.getLogger(ApacheResponseFuture.class);
private Future innerFuture;
private final AsyncHandler asyncHandler;
private final int responseTimeoutInMs;
private final AtomicBoolean cancelled = new AtomicBoolean(false);
private final AtomicBoolean timedOut = new AtomicBoolean(false);
private final AtomicBoolean isDone = new AtomicBoolean(false);
private final AtomicReference exception = new AtomicReference();
private final AtomicLong touch = new AtomicLong(millisTime());
private final AtomicBoolean contentProcessed = new AtomicBoolean(false);
private final Request request;
private final HttpMethodBase method;
private Future> reaperFuture;
public ApacheResponseFuture(AsyncHandler asyncHandler, int responseTimeoutInMs, Request request, HttpMethodBase method) {
this.asyncHandler = asyncHandler;
this.responseTimeoutInMs = responseTimeoutInMs == -1 ? Integer.MAX_VALUE : responseTimeoutInMs;
this.request = request;
this.method = method;
}
protected void setInnerFuture(Future innerFuture) {
this.innerFuture = innerFuture;
}
public void done() {
isDone.set(true);
if (reaperFuture != null) {
reaperFuture.cancel(true);
}
runListeners();
}
/**
* TODO.
*
* @param v The new content
*/
public void content(V v) {
}
protected void setReaperFuture(Future> reaperFuture) {
if (this.reaperFuture != null) {
this.reaperFuture.cancel(true);
}
this.reaperFuture = reaperFuture;
}
@Override
public String toString() {
return "ApacheResponseFuture{" +
"innerFuture=" + innerFuture +
", asyncHandler=" + asyncHandler +
", responseTimeoutInMs=" + responseTimeoutInMs +
", cancelled=" + cancelled +
", timedOut=" + timedOut +
", isDone=" + isDone +
", exception=" + exception +
", touch=" + touch +
", contentProcessed=" + contentProcessed +
", request=" + request +
", method=" + method +
", reaperFuture=" + reaperFuture +
'}';
}
public void abort(Throwable t) {
exception.set(t);
if (innerFuture != null) {
innerFuture.cancel(true);
}
if (method != null) {
method.abort();
}
if (reaperFuture != null) {
reaperFuture.cancel(true);
}
if (!timedOut.get() && !cancelled.get()) {
try {
asyncHandler.onThrowable(t);
} catch (Throwable t2) {
logger.debug("asyncHandler.onThrowable", t2);
}
}
runListeners();
}
public boolean cancel(boolean mayInterruptIfRunning) {
if (!cancelled.get() && innerFuture != null) {
method.abort();
try {
asyncHandler.onThrowable(new CancellationException());
} catch (Throwable t) {
logger.debug("asyncHandler.onThrowable", t);
}
cancelled.set(true);
if (reaperFuture != null) {
reaperFuture.cancel(true);
}
runListeners();
return innerFuture.cancel(mayInterruptIfRunning);
} else {
runListeners();
return false;
}
}
public boolean isCancelled() {
if (innerFuture != null) {
return innerFuture.isCancelled();
} else {
return false;
}
}
public boolean isDone() {
contentProcessed.set(true);
return innerFuture.isDone();
}
public V get() throws InterruptedException, ExecutionException {
try {
return get(responseTimeoutInMs, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
throw new ExecutionException(e);
}
}
public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
V content = null;
try {
if (innerFuture != null) {
content = innerFuture.get(timeout, unit);
}
} catch (TimeoutException t) {
if (!contentProcessed.get() && timeout != -1 && ((millisTime() - touch.get()) <= responseTimeoutInMs)) {
return get(timeout, unit);
}
if (exception.get() == null) {
timedOut.set(true);
throw new ExecutionException(new TimeoutException(String.format("No response received after %s", responseTimeoutInMs)));
}
} catch (CancellationException ce) {
}
if (exception.get() != null) {
throw new ExecutionException(exception.get());
}
return content;
}
/**
* Is the Future still valid
*
* @return true if response has expired and should be terminated.
*/
public boolean hasExpired() {
return responseTimeoutInMs != -1 && ((millisTime() - touch.get()) >= responseTimeoutInMs);
}
public void touch() {
touch.set(millisTime());
}
public Request getRequest() {
return request;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy