Retry.java
package org.flasby.util.time;
import java.io.Closeable;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* retries something until
*/
public abstract class Retry<T extends Retry.Retryable> implements Closeable {
public static interface Retryable extends Closeable {
public Retryable initialize() throws RuntimeException;
}
private ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
private final T retryable;
public Retry(int period, TimeUnit unit) {
this.retryable = createRetryable();
}
final T getRetryable() {
try {
CompletableFuture<Retryable> xxx = CompletableFuture.supplyAsync(() -> retryable.initialize() ).handle((s, t) -> {
System.err.println("goat: "+s);
return s != null ? s : getRetryable();
});
// System.err.println("Tonk "+xxx.get() );
//return xxx.get();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return retryable;
}
public final void close() throws IOException {
retryable.close();
}
public abstract T createRetryable();
static class X implements Retryable {
int x = -2;
@Override
public X initialize() throws RuntimeException {
System.err.println("X: "+x);
if ( x++ != 0 ) throw new RuntimeException("x="+x);
return this;
}
@Override
public void close() throws IOException {
System.err.println("Closing");
}
public void grunt() {
System.err.println("Grunt: "+x);
}
}
public static void main(String[] args) {
try (Retry<X> r = new Retry<X>(1, TimeUnit.SECONDS) {
@Override
public X createRetryable() {
return new X();
}
}) {
X x = r.getRetryable();
x.grunt();
} catch ( IOException ex ) {
ex.printStackTrace();
}
}
}