HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

connect in a background until success

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
connectbackgrounduntilsuccess

Problem

We have some required services down temporarily when our server start. So we need some reconnection logic for them until they are finally up.
There is a requirement to have also syncronious way for that.
Here is my generic implementation for that via a single background thread:

```
public class RunUntilSuccess {

private static final Logger log = LoggerFactory.getLogger(RunUntilSuccess.class);

private final String processName;
private final Task task;
private final int maxAttempts;
private final int interval;
private final TimeUnit unit;
private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
private AtomicInteger count = new AtomicInteger(0);

public RunUntilSuccess(String processName, Callable task, int interval, TimeUnit unit) {
this(processName, task, interval, unit, -1);
}

public RunUntilSuccess(String processName, Callable callable, int interval, TimeUnit unit, int maxAttempts) {
if (callable == null) {
throw new IllegalArgumentException("Callable cannot be null");
}
this.processName = processName;
this.task = new Task(callable);
this.interval = Math.max(0, interval);
if (unit == null) {
throw new IllegalArgumentException("Unit cannot be null");
}
this.unit = unit;
this.maxAttempts = (maxAttempts > 0) ? maxAttempts : -1;

start();
}

private void start() {
log.debug("Starting task execution. " + toString());
executor.scheduleWithFixedDelay(task, 0, interval, unit);
}

/**
* Wait until success
*/
public void await() throws InterruptedException {
while (!executor.awaitTermination(interval, unit)) { }
}

public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
return executor.awaitTermination(timeout, unit);
}

private boolean isAttemptsLimitReached(int attempt){
return (maxAttempts > 0) && (attempt >= maxAttempts);
}

@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append

Solution

Your use of executor.awaitTermination() seems odd to me. I would instead have used a CountdownLatch to trigger success in a blocked thread. But I also agree with @Craig P. Motlin that a Future makes sense.

Besides that specific comment, you might consider some asynchronous notification technique for the dependency to declare that it's alive. That might be overkill for your scenario, but it's worked for me. Jini service registry, JMS messages, Hazelcast, plain UDP multicast, etc.

Context

StackExchange Code Review Q#3246, answer score: 2

Revisions (0)

No revisions yet.