com.ning.http.client.providers.jdk.JDKFuture Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payment-retries-plugin Show documentation
Show all versions of payment-retries-plugin Show documentation
Kill Bill Payment Retries plugin
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.jdk;
import static com.ning.http.util.DateUtils.millisTime;
import com.ning.http.client.AsyncHandler;
import com.ning.http.client.listenable.AbstractListenableFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.HttpURLConnection;
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 JDKFuture extends AbstractListenableFuture {
private final static Logger logger = LoggerFactory.getLogger(JDKFuture.class);
protected Future innerFuture;
protected final AsyncHandler asyncHandler;
protected final int responseTimeoutInMs;
protected final AtomicBoolean cancelled = new AtomicBoolean(false);
protected final AtomicBoolean timedOut = new AtomicBoolean(false);
protected final AtomicBoolean isDone = new AtomicBoolean(false);
protected final AtomicReference exception = new AtomicReference();
protected final AtomicLong touch = new AtomicLong(millisTime());
protected final AtomicBoolean contentProcessed = new AtomicBoolean(false);
protected final HttpURLConnection urlConnection;
public JDKFuture(AsyncHandler asyncHandler, int responseTimeoutInMs, HttpURLConnection urlConnection) {
this.asyncHandler = asyncHandler;
this.responseTimeoutInMs = responseTimeoutInMs;
this.urlConnection = urlConnection;
}
protected void setInnerFuture(Future innerFuture) {
this.innerFuture = innerFuture;
}
public void done() {
isDone.set(true);
runListeners();
}
public void abort(Throwable t) {
exception.set(t);
if (innerFuture != null) {
innerFuture.cancel(true);
}
if (!timedOut.get() && !cancelled.get()) {
try {
asyncHandler.onThrowable(t);
} catch (Throwable te) {
logger.debug("asyncHandler.onThrowable", te);
}
}
runListeners();
}
public void content(V v) {
}
public boolean cancel(boolean mayInterruptIfRunning) {
if (!cancelled.get() && innerFuture != null) {
urlConnection.disconnect();
try {
asyncHandler.onThrowable(new CancellationException());
} catch (Throwable te) {
logger.debug("asyncHandler.onThrowable", te);
}
cancelled.set(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);
}
@Override
public void touch() {
touch.set(millisTime());
}
}