First of all, the retry mechanism did not work at all until now (if a task was retried ExecutableRunnable would stack overflow).
Secondly, ExecutableRunnable now prevents retryTasks from being called too frequently. If it detects that retryTasks was called twice in 30 seconds, it reschedules the call 30 seconds later.
import java.util.LinkedList;
import java.util.Queue;
import java.util.LinkedList;
import java.util.Queue;
-import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import android.os.SystemClock;
/*
* Copyright © 2013 Marius Gavrilescu
/*
* Copyright © 2013 Marius Gavrilescu
*/
abstract class ExecutableRunnable implements Runnable {
/** Executor used to execute instances of this class */
*/
abstract class ExecutableRunnable implements Runnable {
/** Executor used to execute instances of this class */
- private static final Executor executor = Executors.newSingleThreadExecutor();
+ private static final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
/** Queue containing <code>ExecutableRunnable</code>s that should be retried */
private static final Queue<ExecutableRunnable> retryPendingTasks = new LinkedList<ExecutableRunnable>();
/** Queue containing <code>ExecutableRunnable</code>s that should be retried */
private static final Queue<ExecutableRunnable> retryPendingTasks = new LinkedList<ExecutableRunnable>();
+ /** Minimum interval between task retries, in milliseconds */
+ private static final long retryInterval = 30000;
+ /** {@link SystemClock#elapsedRealtime()} time of last successful call to {@link #retryTasks()} */
+ private static long lastRetry = 0;
+ /** True if a retryTasks run is already scheduled on {@link #executor} */
+ private static volatile boolean retryIsScheduled = false;
/** Run all tasks that should be retried */
public static final void retryTasks(){
/** Run all tasks that should be retried */
public static final void retryTasks(){
+ if(!retryIsScheduled && lastRetry+retryInterval>SystemClock.elapsedRealtime()){
+ retryIsScheduled = true;
+ executor.schedule(new Runnable() {
+ @Override
+ public void run() {
+ retryTasks();
+ retryIsScheduled = false;
+ }
+ }, retryInterval, TimeUnit.MILLISECONDS);
+ return;
+ }
synchronized(retryPendingTasks){
for(ExecutableRunnable task : retryPendingTasks)
synchronized(retryPendingTasks){
for(ExecutableRunnable task : retryPendingTasks)
+ executor.execute(task);
retryPendingTasks.clear();
}
retryPendingTasks.clear();
}
+ lastRetry=SystemClock.elapsedRealtime();
}
/** Execute this <code>ExecutableRunnable</code> */
}
/** Execute this <code>ExecutableRunnable</code> */