Cap concurrent removal DownloadManager.Tasks

This commit is contained in:
Jorge Antonio Diaz-Benito Soriano 2022-07-21 14:38:47 +02:00
parent 9271572e95
commit 28e32072b6
No known key found for this signature in database
GPG Key ID: 9E0D738D682347F5
2 changed files with 65 additions and 2 deletions

View File

@ -174,6 +174,7 @@ public final class DownloadManager {
private static final int MSG_RELEASE = 12;
private static final String TAG = "DownloadManager";
private static final int MAX_REMOVE_TASK_COUNT = 1;
private final Context context;
private final WritableDownloadIndex downloadIndex;
@ -709,6 +710,7 @@ public final class DownloadManager {
private int maxParallelDownloads;
private int minRetryCount;
private int activeDownloadTaskCount;
private int activeRemoveTaskCount;
public InternalHandler(
HandlerThread thread,
@ -1060,6 +1062,10 @@ public final class DownloadManager {
return;
}
if (activeRemoveTaskCount >= MAX_REMOVE_TASK_COUNT) {
return;
}
// We can start a remove task.
Downloader downloader = downloaderFactory.createDownloader(download.request);
activeTask =
@ -1071,6 +1077,7 @@ public final class DownloadManager {
minRetryCount,
/* internalHandler= */ this);
activeTasks.put(download.request.id, activeTask);
activeRemoveTaskCount++;
activeTask.start();
}
@ -1100,7 +1107,9 @@ public final class DownloadManager {
activeTasks.remove(downloadId);
boolean isRemove = task.isRemove;
if (!isRemove && --activeDownloadTaskCount == 0) {
if (isRemove) {
activeRemoveTaskCount--;
} else if (--activeDownloadTaskCount == 0) {
removeMessages(MSG_UPDATE_PROGRESS);
}

View File

@ -713,7 +713,61 @@ public class DownloadManagerTest {
assertEqualIgnoringUpdateTime(mergedDownload, expectedDownload);
}
@Test
public void remove_tasks_run_sequentially()
throws Throwable {
DefaultDownloadIndex defaultDownloadIndex =
new DefaultDownloadIndex(TestUtil.getInMemoryDatabaseProvider());
defaultDownloadIndex.putDownload(
new Download(
new DownloadRequest.Builder(ID1, Uri.EMPTY).build(),
Download.STATE_REMOVING,
0,
1,
2,
Download.STOP_REASON_NONE,
Download.FAILURE_REASON_NONE
)
);
defaultDownloadIndex.putDownload(
new Download(
new DownloadRequest.Builder(ID2, Uri.EMPTY).build(),
Download.STATE_RESTARTING,
0,
1,
2,
Download.STOP_REASON_NONE,
Download.FAILURE_REASON_NONE
)
);
setupDownloadManager(100, defaultDownloadIndex);
// The second removal should wait and the first one should be able to complete.
FakeDownloader downloader0 = getDownloaderAt(0);
assertNoDownloaderAt(1);
downloader0.assertId(ID1);
downloader0.assertRemoveStarted();
downloader0.finish();
assertRemoved(ID1);
// The second removal can start once the first one has completed, and removes a download with
// state STATE_RESTARTING, so it should result in a new download being queued.
FakeDownloader downloader1 = getDownloaderAt(1);
downloader1.assertId(ID2);
downloader1.assertRemoveStarted();
downloader1.finish();
assertQueued(ID2);
}
private void setupDownloadManager(int maxParallelDownloads) throws Exception {
setupDownloadManager(
maxParallelDownloads, new DefaultDownloadIndex(TestUtil.getInMemoryDatabaseProvider())
);
}
private void setupDownloadManager(
int maxParallelDownloads, WritableDownloadIndex writableDownloadIndex
) throws Exception {
if (downloadManager != null) {
releaseDownloadManager();
}
@ -723,7 +777,7 @@ public class DownloadManagerTest {
downloadManager =
new DownloadManager(
ApplicationProvider.getApplicationContext(),
new DefaultDownloadIndex(TestUtil.getInMemoryDatabaseProvider()),
writableDownloadIndex,
new FakeDownloaderFactory());
downloadManager.setMaxParallelDownloads(maxParallelDownloads);
downloadManager.setMinRetryCount(MIN_RETRY_COUNT);