Wait for download completion on initial sync

This commit is contained in:
ByteHamster 2021-10-06 20:44:49 +02:00
parent bc85ebc806
commit 1b1b05bfff
4 changed files with 36 additions and 14 deletions

View File

@ -20,7 +20,6 @@ import androidx.annotation.VisibleForTesting;
import androidx.core.app.ServiceCompat; import androidx.core.app.ServiceCompat;
import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.sync.SyncService;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.EventBus;
@ -227,10 +226,6 @@ public class DownloadService extends Service {
} }
unregisterReceiver(cancelDownloadReceiver); unregisterReceiver(cancelDownloadReceiver);
// if this was the initial gpodder sync, i.e. we just synced the feeds successfully,
// it is now time to sync the episode actions
SyncService.sync(this);
// start auto download in case anything new has shown up // start auto download in case anything new has shown up
DBTasks.autodownloadUndownloadedItems(getApplicationContext()); DBTasks.autodownloadUndownloadedItems(getApplicationContext());
} }

View File

@ -22,7 +22,6 @@ public class EpisodeActionFilter {
Map<Pair<String, String>, EpisodeAction> localMostRecentPlayActions = Map<Pair<String, String>, EpisodeAction> localMostRecentPlayActions =
createUniqueLocalMostRecentPlayActions(queuedEpisodeActions); createUniqueLocalMostRecentPlayActions(queuedEpisodeActions);
for (EpisodeAction remoteAction : remoteActions) { for (EpisodeAction remoteAction : remoteActions) {
Log.d(TAG, "Processing remoteAction: " + remoteAction.toString());
Pair<String, String> key = new Pair<>(remoteAction.getPodcast(), remoteAction.getEpisode()); Pair<String, String> key = new Pair<>(remoteAction.getPodcast(), remoteAction.getEpisode());
switch (remoteAction.getAction()) { switch (remoteAction.getAction()) {
case NEW: case NEW:

View File

@ -55,8 +55,9 @@ import de.danoeh.antennapod.net.sync.nextcloud.NextcloudSyncService;
public class SyncService extends Worker { public class SyncService extends Worker {
public static final String TAG = "SyncService"; public static final String TAG = "SyncService";
private static final String WORK_ID_SYNC = "SyncServiceWorkId"; private static final String WORK_ID_SYNC = "SyncServiceWorkId";
private static boolean isCurrentlyActive = false;
private final SynchronizationQueueStorage synchronizationQueueStorage; private final SynchronizationQueueStorage synchronizationQueueStorage;
public SyncService(@NonNull Context context, @NonNull WorkerParameters params) { public SyncService(@NonNull Context context, @NonNull WorkerParameters params) {
@ -73,10 +74,11 @@ public class SyncService extends Worker {
} }
SynchronizationSettings.updateLastSynchronizationAttempt(); SynchronizationSettings.updateLastSynchronizationAttempt();
setCurrentlyActive(true);
try { try {
activeSyncProvider.login(); activeSyncProvider.login();
EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_subscriptions));
syncSubscriptions(activeSyncProvider); syncSubscriptions(activeSyncProvider);
waitForDownloadServiceCompleted();
syncEpisodeActions(activeSyncProvider); syncEpisodeActions(activeSyncProvider);
activeSyncProvider.logout(); activeSyncProvider.logout();
clearErrorNotifications(); clearErrorNotifications();
@ -98,13 +100,18 @@ public class SyncService extends Worker {
updateErrorNotification(e); updateErrorNotification(e);
return Result.failure(); return Result.failure();
} }
} finally {
setCurrentlyActive(false);
} }
} }
private static void setCurrentlyActive(boolean active) {
isCurrentlyActive = active;
}
public static void sync(Context context) { public static void sync(Context context) {
OneTimeWorkRequest workRequest = getWorkRequest().build(); OneTimeWorkRequest workRequest = getWorkRequest().build();
WorkManager.getInstance(context).enqueueUniqueWork(WORK_ID_SYNC, ExistingWorkPolicy.REPLACE, workRequest); WorkManager.getInstance(context).enqueueUniqueWork(WORK_ID_SYNC, ExistingWorkPolicy.REPLACE, workRequest);
EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_started));
} }
public static void syncImmediately(Context context) { public static void syncImmediately(Context context) {
@ -112,7 +119,6 @@ public class SyncService extends Worker {
.setInitialDelay(0L, TimeUnit.SECONDS) .setInitialDelay(0L, TimeUnit.SECONDS)
.build(); .build();
WorkManager.getInstance(context).enqueueUniqueWork(WORK_ID_SYNC, ExistingWorkPolicy.REPLACE, workRequest); WorkManager.getInstance(context).enqueueUniqueWork(WORK_ID_SYNC, ExistingWorkPolicy.REPLACE, workRequest);
EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_started));
} }
public static void fullSync(Context context) { public static void fullSync(Context context) {
@ -122,12 +128,12 @@ public class SyncService extends Worker {
.setInitialDelay(0L, TimeUnit.SECONDS) .setInitialDelay(0L, TimeUnit.SECONDS)
.build(); .build();
WorkManager.getInstance(context).enqueueUniqueWork(WORK_ID_SYNC, ExistingWorkPolicy.REPLACE, workRequest); WorkManager.getInstance(context).enqueueUniqueWork(WORK_ID_SYNC, ExistingWorkPolicy.REPLACE, workRequest);
EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_started));
}); });
} }
private void syncSubscriptions(ISyncService syncServiceImpl) throws SyncServiceException { private void syncSubscriptions(ISyncService syncServiceImpl) throws SyncServiceException {
final long lastSync = SynchronizationSettings.getLastSubscriptionSynchronizationTimestamp(); final long lastSync = SynchronizationSettings.getLastSubscriptionSynchronizationTimestamp();
EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_subscriptions));
final List<String> localSubscriptions = DBReader.getFeedListDownloadUrls(); final List<String> localSubscriptions = DBReader.getFeedListDownloadUrls();
SubscriptionChanges subscriptionChanges = syncServiceImpl.getSubscriptionChanges(lastSync); SubscriptionChanges subscriptionChanges = syncServiceImpl.getSubscriptionChanges(lastSync);
long newTimeStamp = subscriptionChanges.getTimestamp(); long newTimeStamp = subscriptionChanges.getTimestamp();
@ -178,6 +184,18 @@ public class SyncService extends Worker {
SynchronizationSettings.setLastSubscriptionSynchronizationAttemptTimestamp(newTimeStamp); SynchronizationSettings.setLastSubscriptionSynchronizationAttemptTimestamp(newTimeStamp);
} }
private void waitForDownloadServiceCompleted() {
EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_wait_for_downloads));
try {
while (DownloadRequester.getInstance().isDownloadingFeeds()) {
//noinspection BusyWait
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void syncEpisodeActions(ISyncService syncServiceImpl) throws SyncServiceException { private void syncEpisodeActions(ISyncService syncServiceImpl) throws SyncServiceException {
final long lastSync = SynchronizationSettings.getLastEpisodeActionSynchronizationTimestamp(); final long lastSync = SynchronizationSettings.getLastEpisodeActionSynchronizationTimestamp();
EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_episodes_download)); EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_episodes_download));
@ -308,10 +326,19 @@ public class SyncService extends Worker {
constraints.setRequiredNetworkType(NetworkType.UNMETERED); constraints.setRequiredNetworkType(NetworkType.UNMETERED);
} }
return new OneTimeWorkRequest.Builder(SyncService.class) OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(SyncService.class)
.setConstraints(constraints.build()) .setConstraints(constraints.build())
.setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 10, TimeUnit.MINUTES) .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 10, TimeUnit.MINUTES);
.setInitialDelay(5L, TimeUnit.SECONDS); // Give it some time, so other actions can be queued
if (isCurrentlyActive) {
// Debounce: don't start sync again immediately after it was finished.
builder.setInitialDelay(2L, TimeUnit.MINUTES);
} else {
// Give it some time, so other possible actions can be queued.
builder.setInitialDelay(20L, TimeUnit.SECONDS);
EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_started));
}
return builder;
} }
private ISyncService getActiveSyncProvider() { private ISyncService getActiveSyncProvider() {

View File

@ -568,6 +568,7 @@
<string name="sync_status_episodes_download">Downloading episode changes…</string> <string name="sync_status_episodes_download">Downloading episode changes…</string>
<string name="sync_status_upload_played">Uploading played status…</string> <string name="sync_status_upload_played">Uploading played status…</string>
<string name="sync_status_subscriptions">Synchronizing subscriptions…</string> <string name="sync_status_subscriptions">Synchronizing subscriptions…</string>
<string name="sync_status_wait_for_downloads">Waiting for downloads to complete…</string>
<string name="sync_status_success">Synchronization successful</string> <string name="sync_status_success">Synchronization successful</string>
<string name="sync_status_error">Synchronization failed</string> <string name="sync_status_error">Synchronization failed</string>