Keep retrying message sends for 24 hours.
Previously, we retried based on a count. Now we've added the ability to keep retrying for a specified time, using exponential backoff to throttle attempts.pull/1/head
parent
cddb8082f4
commit
a50edc3d25
@ -0,0 +1,35 @@
|
||||
package org.thoughtcrime.securesms.jobmanager.requirements;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.ApplicationContext;
|
||||
import org.thoughtcrime.securesms.BuildConfig;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class BackoffReceiver extends BroadcastReceiver {
|
||||
|
||||
private static final String TAG = BackoffReceiver.class.getSimpleName();
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Log.i(TAG, "Received an alarm to retry a job with ID: " + intent.getAction());
|
||||
ApplicationContext.getInstance(context).getJobManager().onRequirementStatusChanged();
|
||||
}
|
||||
|
||||
public static void setUniqueAlarm(@NonNull Context context, long time) {
|
||||
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
Intent intent = new Intent(context, BackoffReceiver.class);
|
||||
|
||||
intent.setAction(BuildConfig.APPLICATION_ID + UUID.randomUUID().toString());
|
||||
alarmManager.set(AlarmManager.RTC_WAKEUP, time, PendingIntent.getBroadcast(context, 0, intent, 0));
|
||||
|
||||
Log.i(TAG, "Set an alarm to retry a job in " + (time - System.currentTimeMillis()) + " ms with ID: " + intent.getAction());
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package org.thoughtcrime.securesms.jobmanager.requirements;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.dependencies.ContextDependent;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Uses exponential backoff to re-schedule network jobs to be retried in the future.
|
||||
*/
|
||||
public class NetworkBackoffRequirement implements Requirement, ContextDependent {
|
||||
|
||||
private static final long MAX_WAIT = TimeUnit.SECONDS.toMillis(30);
|
||||
|
||||
private transient Context context;
|
||||
|
||||
public NetworkBackoffRequirement(@NonNull Context context) {
|
||||
this.context = context.getApplicationContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPresent(@NonNull Job job) {
|
||||
return new NetworkRequirement(context).isPresent() && System.currentTimeMillis() >= calculateNextRunTime(job);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetry(@NonNull Job job) {
|
||||
if (!(new NetworkRequirement(context).isPresent())) {
|
||||
job.resetRunStats();
|
||||
return;
|
||||
}
|
||||
|
||||
BackoffReceiver.setUniqueAlarm(context, NetworkBackoffRequirement.calculateNextRunTime(job));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContext(Context context) {
|
||||
this.context = context.getApplicationContext();
|
||||
}
|
||||
|
||||
private static long calculateNextRunTime(@NonNull Job job) {
|
||||
long targetTime = job.getLastRunTime() + (long) (Math.pow(2, job.getRunIteration() - 1) * 1000);
|
||||
long furthestTime = System.currentTimeMillis() + MAX_WAIT;
|
||||
|
||||
return Math.min(targetTime, Math.min(furthestTime, job.getRetryUntil()));
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package org.thoughtcrime.securesms.jobmanager.requirements;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
|
||||
public abstract class SimpleRequirement implements Requirement {
|
||||
|
||||
@Override
|
||||
public boolean isPresent(@NonNull Job job) {
|
||||
return isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetry(@NonNull Job job) {
|
||||
}
|
||||
|
||||
public abstract boolean isPresent();
|
||||
}
|
Loading…
Reference in New Issue