Auto adjust keep alive interval

This commit is contained in:
M66B 2019-07-08 16:48:59 +02:00
parent d7ca03cfbb
commit db1ea29fbf
2 changed files with 30 additions and 6 deletions

View File

@ -126,6 +126,9 @@ public interface DaoAccount {
@Query("UPDATE account SET error = :error WHERE id = :id") @Query("UPDATE account SET error = :error WHERE id = :id")
int setAccountError(long id, String error); int setAccountError(long id, String error);
@Query("UPDATE account SET poll_interval = :poll_interval WHERE id = :id")
int setAccountPollInterval(long id, int poll_interval);
@Query("UPDATE account SET `primary` = 0") @Query("UPDATE account SET `primary` = 0")
void resetPrimary(); void resetPrimary();

View File

@ -557,6 +557,8 @@ public class ServiceSynchronize extends LifecycleService {
final DB db = DB.getInstance(this); final DB db = DB.getInstance(this);
int backoff = CONNECT_BACKOFF_START; int backoff = CONNECT_BACKOFF_START;
int poll_count = 0;
int poll_interval = account.poll_interval;
while (state.running()) { while (state.running()) {
state.reset(); state.reset();
Log.i(account.name + " run"); Log.i(account.name + " run");
@ -708,7 +710,7 @@ public class ServiceSynchronize extends LifecycleService {
EntityLog.log(this, account.name + " last connected: " + new Date(account.last_connected)); EntityLog.log(this, account.name + " last connected: " + new Date(account.last_connected));
long now = new Date().getTime(); long now = new Date().getTime();
long delayed = now - account.last_connected - account.poll_interval * 60 * 1000L; long delayed = now - account.last_connected - poll_interval * 60 * 1000L;
if (delayed > ACCOUNT_ERROR_AFTER * 60 * 1000L && backoff > BACKOFF_ERROR_AFTER) { if (delayed > ACCOUNT_ERROR_AFTER * 60 * 1000L && backoff > BACKOFF_ERROR_AFTER) {
Log.i("Reporting sync error after=" + delayed); Log.i("Reporting sync error after=" + delayed);
Throwable warning = new Throwable( Throwable warning = new Throwable(
@ -1098,13 +1100,32 @@ public class ServiceSynchronize extends LifecycleService {
while (state.running()) { while (state.running()) {
if (!state.recoverable()) if (!state.recoverable())
throw new StoreClosedException(istore, "Unrecoverable"); throw new StoreClosedException(istore, "Unrecoverable");
if (!istore.isConnected()) // Sends store NOOP // Sends store NOOP
if (istore.isConnected()) {
poll_count++;
EntityLog.log(this, account.name + " poll count=" + poll_count);
if (capIdle && poll_count >= 3 && poll_interval != account.poll_interval) {
Log.w(account.host + " keep alive " + account.poll_interval + " > " + poll_interval);
EntityLog.log(this, account.name + " adjusting keep alive interval" +
" from " + account.poll_interval + " to " + poll_interval);
db.account().setAccountPollInterval(account.id, poll_interval);
account.poll_interval = poll_interval;
}
} else {
poll_count = 0;
if (capIdle && poll_interval > 9) {
poll_interval -= Math.ceil(poll_interval * 0.1f);
EntityLog.log(this, account.name + " decreased keep alive interval" +
" to " + poll_interval);
}
throw new StoreClosedException(istore, "NOOP"); throw new StoreClosedException(istore, "NOOP");
}
for (EntityFolder folder : mapFolders.keySet()) for (EntityFolder folder : mapFolders.keySet())
if (folder.synchronize) if (folder.synchronize)
if (!folder.poll && capIdle) { if (!folder.poll && capIdle) {
if (!mapFolders.get(folder).isOpen()) // Sends folder NOOP // Sends folder NOOP
if (!mapFolders.get(folder).isOpen())
throw new StoreClosedException(istore, folder.name); throw new StoreClosedException(istore, folder.name);
} else } else
EntityOperation.sync(this, folder.id, false); EntityOperation.sync(this, folder.id, false);
@ -1122,16 +1143,16 @@ public class ServiceSynchronize extends LifecycleService {
nm.cancel("receive:" + account.id, 1); nm.cancel("receive:" + account.id, 1);
// Schedule keep alive alarm // Schedule keep alive alarm
EntityLog.log(this, account.name + " wait=" + account.poll_interval); EntityLog.log(this, account.name + " wait=" + poll_interval);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
am.set( am.set(
AlarmManager.RTC_WAKEUP, AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + account.poll_interval * 60 * 1000L, System.currentTimeMillis() + poll_interval * 60 * 1000L,
pi); pi);
else else
am.setAndAllowWhileIdle( am.setAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP, AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + account.poll_interval * 60 * 1000L, System.currentTimeMillis() + poll_interval * 60 * 1000L,
pi); pi);
try { try {