diff --git a/app/src/main/java/eu/faircode/email/Core.java b/app/src/main/java/eu/faircode/email/Core.java
index 41e5b25e04..d6c0df2360 100644
--- a/app/src/main/java/eu/faircode/email/Core.java
+++ b/app/src/main/java/eu/faircode/email/Core.java
@@ -145,10 +145,6 @@ class Core {
private static final long SCREEN_ON_DURATION = 3000L; // milliseconds
private static final int SYNC_BATCH_SIZE = 20;
private static final int DOWNLOAD_BATCH_SIZE = 20;
- private static final int SYNC_YIELD_COUNT = 100;
- private static final long SYNC_YIELD_DURATION = 1000; // milliseconds
- private static final int DOWNLOAD_YIELD_COUNT = 25;
- private static final long DOWNLOAD_YIELD_DURATION = 1000; // milliseconds
private static final long YIELD_DURATION = 200L; // milliseconds
private static final long JOIN_WAIT_ALIVE = 5 * 60 * 1000L; // milliseconds
private static final long JOIN_WAIT_INTERRUPT = 1 * 60 * 1000L; // milliseconds
@@ -3483,7 +3479,7 @@ class Core {
fp.add(GmailFolder.FetchProfileItem.THRID);
// Add/update local messages
- int synced = 0;
+ DutyCycle dc = new DutyCycle(account.name + " sync");
Log.i(folder.name + " add=" + imessages.length);
for (int i = imessages.length - 1; i >= 0; i -= SYNC_BATCH_SIZE) {
state.ensureRunning("Sync/IMAP/sync/fetch");
@@ -3522,6 +3518,8 @@ class Core {
state.ensureRunning("Sync/IMAP/sync");
try {
+ dc.start();
+
// Some providers erroneously return old messages
if (full.contains(isub[j]))
try {
@@ -3545,15 +3543,6 @@ class Core {
false, download && initialize == 0,
rules, state, stats);
ids[from + j] = (message == null || message.ui_hide ? null : message.id);
-
- if (message != null && full.contains(isub[j]))
- if ((++synced % SYNC_YIELD_COUNT) == 0)
- try {
- Log.i(folder.name + " yield synced=" + synced);
- Thread.sleep(SYNC_YIELD_DURATION);
- } catch (InterruptedException ex) {
- Log.w(ex);
- }
} catch (MessageRemovedException ex) {
Log.w(folder.name, ex);
} catch (FolderClosedException ex) {
@@ -3570,6 +3559,7 @@ class Core {
} finally {
// Free memory
isub[j] = null;
+ dc.stop();
}
}
}
@@ -3617,7 +3607,7 @@ class Core {
db.folder().setFolderSyncState(folder.id, "downloading");
// Download messages/attachments
- int downloaded = 0;
+ DutyCycle dc = new DutyCycle(account.name + " download");
Log.i(folder.name + " download=" + imessages.length);
for (int i = imessages.length - 1; i >= 0; i -= DOWNLOAD_BATCH_SIZE) {
state.ensureRunning("Sync/IMAP/download/fetch");
@@ -3642,22 +3632,14 @@ class Core {
state.ensureRunning("Sync/IMAP/download");
try {
- if (ids[from + j] != null) {
- boolean fetched = downloadMessage(
+ dc.start();
+ if (ids[from + j] != null)
+ downloadMessage(
context,
account, folder,
istore, ifolder,
(MimeMessage) isub[j], ids[from + j],
state, stats);
- if (fetched)
- if ((++downloaded % DOWNLOAD_YIELD_COUNT) == 0)
- try {
- Log.i(folder.name + " yield downloaded=" + downloaded);
- Thread.sleep(DOWNLOAD_YIELD_DURATION);
- } catch (InterruptedException ex) {
- Log.w(ex);
- }
- }
} catch (FolderClosedException ex) {
throw ex;
} catch (Throwable ex) {
@@ -3665,6 +3647,7 @@ class Core {
} finally {
// Free memory
isub[j] = null;
+ dc.stop();
}
}
}
diff --git a/app/src/main/java/eu/faircode/email/DutyCycle.java b/app/src/main/java/eu/faircode/email/DutyCycle.java
new file mode 100644
index 0000000000..9ad9914b40
--- /dev/null
+++ b/app/src/main/java/eu/faircode/email/DutyCycle.java
@@ -0,0 +1,73 @@
+package eu.faircode.email;
+
+/*
+ This file is part of FairEmail.
+
+ FairEmail is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ FairEmail is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FairEmail. If not, see .
+
+ Copyright 2018-2022 by Marcel Bokhorst (M66B)
+*/
+
+import java.util.Date;
+
+public class DutyCycle {
+ private final String name;
+ private final long interval;
+ private final long duration;
+
+ private Long last = null;
+ private long start;
+ private long idle = 0;
+ private long busy = 0;
+
+ private static final long YIELD_INTERVAL = 15 * 1000L; // milliseconds
+ private static final long YIELD_DURATION = 1500L; // milliseconds
+
+ public DutyCycle(String name) {
+ this(name, YIELD_INTERVAL, YIELD_DURATION);
+ }
+
+ public DutyCycle(String name, long interval, long duration) {
+ this.name = name;
+ this.interval = interval;
+ this.duration = duration;
+ }
+
+ public void start() {
+ start = new Date().getTime();
+ }
+
+ public void stop() {
+ long end = new Date().getTime();
+
+ if (last != null)
+ idle += (start - last);
+ last = end;
+
+ busy += (end - start);
+
+ if (busy + idle > interval) {
+ long wait = (duration - idle);
+ Log.i(name + " busy=" + busy + " idle=" + idle + " wait=" + wait);
+ if (wait > 0)
+ try {
+ Thread.sleep(wait);
+ } catch (InterruptedException ex) {
+ Log.w(ex);
+ }
+ idle = 0;
+ busy = 0;
+ }
+ }
+}
diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java
index 9a1c851dd1..a60a0d4219 100644
--- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java
+++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java
@@ -137,8 +137,6 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences
private static final int FAST_FAIL_COUNT = 3;
private static final int FETCH_YIELD_DURATION = 50; // milliseconds
private static final long WATCHDOG_INTERVAL = 60 * 60 * 1000L; // milliseconds
- private static final long OPS_YIELD_INTERVAL = 15 * 1000L; // milliseconds
- private static final long OPS_YIELD_DURATION = 500L; // milliseconds
private static final String ACTION_NEW_MESSAGE_COUNT = BuildConfig.APPLICATION_ID + ".NEW_MESSAGE_COUNT";
@@ -1819,8 +1817,7 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences
cowner.value.start();
db.operation().liveOperations(account.id).observe(cowner.value, new Observer>() {
- private Long last = null;
- private long idle = 0, busy = 0;
+ private DutyCycle dc = new DutyCycle(account.name + " operations");
private List handling = new ArrayList<>();
private final Map> partitions = new HashMap<>();
@@ -1987,31 +1984,15 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences
Log.i(account.name + " folder " + folder.name + " flags=" + ifolder.getPermanentFlags());
}
- long start = new Date().getTime();
try {
+ dc.start();
Core.processOperations(ServiceSynchronize.this,
account, folder,
partition,
iservice, ifolder,
state, serial);
} finally {
- long end = new Date().getTime();
- if (last != null)
- idle += (start - last);
- last = end;
- busy += (end - start);
- if (busy + idle > OPS_YIELD_INTERVAL) {
- long wait = (OPS_YIELD_DURATION - idle);
- Log.i(account.name + " ops idle wait=" + wait);
- if (wait > 0)
- try {
- Thread.sleep(wait);
- } catch (InterruptedException ex) {
- Log.w(ex);
- }
- idle = 0;
- busy = 0;
- }
+ dc.stop();
}
} catch (Throwable ex) {