jp.gopay.sdk.builders.ResourceMonitor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gopay-java-sdk Show documentation
Show all versions of gopay-java-sdk Show documentation
Official Gyro-n Payments Java SDK
package jp.gopay.sdk.builders;
import jp.gopay.sdk.models.errors.GoPayException;
import jp.gopay.sdk.models.errors.TooManyRequestsException;
import jp.gopay.sdk.utils.Backoff;
import jp.gopay.sdk.utils.ExponentialBackoff;
import jp.gopay.sdk.utils.GoPayCallback;
import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class ResourceMonitor {
final static long DEFAULT_TIMEOUT = 60_000;
private static ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
private RequestBuilder> requestBuilder;
private ResourcePredicate predicate;
public ResourceMonitor(RequestBuilder> requestBuilder, ResourcePredicate predicate) {
this.requestBuilder = requestBuilder;
this.predicate = predicate;
}
Backoff createBackoff(){
return new ExponentialBackoff(0, 30_000, 2, 0.5);
}
long currentTimeMillis() {
return System.currentTimeMillis();
}
void sleep(long millis) throws InterruptedException {
Thread.sleep(millis);
}
void delay(Runnable command, long millis) {
executorService.schedule(command, millis, TimeUnit.MILLISECONDS);
}
public T await() throws IOException, InterruptedException, TimeoutException, GoPayException {
return await(DEFAULT_TIMEOUT);
}
public T await(long timeout) throws IOException, InterruptedException, TimeoutException, GoPayException {
return await(timeout, createBackoff());
}
public T await(long timeout, Backoff backoff) throws IOException, InterruptedException, TimeoutException, GoPayException {
T resource;
final long start = currentTimeMillis();
do {
if (currentTimeMillis() - start > timeout) {
throw new TimeoutException(String.format("Retry timeout exceeded : %dms ", timeout));
}
sleep(backoff.next());
try {
resource = requestBuilder.build().dispatch();
} catch (TooManyRequestsException | IOException e ) {
// retry until timeout exceeded.
resource = null;
}
} while(resource == null || !predicate.test(resource));
return resource;
}
public void await(final GoPayCallback callback) {
await(callback, DEFAULT_TIMEOUT);
}
public void await(final GoPayCallback callback, final long timeout) {
await(callback, timeout, createBackoff());
}
public void await(final GoPayCallback callback, final long timeout, final Backoff backoff) {
final long start = currentTimeMillis();
Runnable runnable = new Runnable() {
@Override
public void run() {
final Runnable self = this;
GoPayCallback command = new GoPayCallback() {
private void retry() {
if (currentTimeMillis() - start > timeout) {
callback.getFailure(new TimeoutException(String.format("Retry timeout exceeded : %dms ", timeout)));
} else {
delay(self, backoff.next());
}
}
@Override
public void getResponse(T response) {
if (predicate.test(response)) {
callback.getResponse(response);
} else {
retry();
}
}
@Override
public void getFailure(Throwable error) {
if (error instanceof TooManyRequestsException || error instanceof IOException) {
retry();
} else {
callback.getFailure(error);
}
}
};
try {
requestBuilder.build().dispatch(command);
} catch (Throwable e) {
callback.getFailure(new Error("Failed to execute request", e));
}
}
};
delay(runnable, backoff.next());
}
}