From c9eefce70d825e047b2f9eb33a1111a2301e4b5e Mon Sep 17 00:00:00 2001 From: LooKeR Date: Wed, 11 Mar 2026 11:11:06 +0530 Subject: [PATCH] perf: Do not launch useless coroutines if permit is not available This commit should stop launching of infinitely stuck infinite coroutines if download speed is slow. We should now be acquiring the semaphore permit before we launch a coroutine which does the actual work Signed-off-by: LooKeR --- .../droidify/work/DownloadStatsWorker.kt | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/app/src/main/kotlin/com/looker/droidify/work/DownloadStatsWorker.kt b/app/src/main/kotlin/com/looker/droidify/work/DownloadStatsWorker.kt index d1fc57692..7c7445ca5 100644 --- a/app/src/main/kotlin/com/looker/droidify/work/DownloadStatsWorker.kt +++ b/app/src/main/kotlin/com/looker/droidify/work/DownloadStatsWorker.kt @@ -27,15 +27,12 @@ import io.ktor.http.HttpStatusCode import java.io.File import java.util.* import java.util.concurrent.ConcurrentLinkedQueue -import kotlin.concurrent.atomics.AtomicInt import kotlin.concurrent.atomics.ExperimentalAtomicApi -import kotlin.concurrent.atomics.incrementAndFetch import kotlin.time.ExperimentalTime import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.supervisorScope import kotlinx.coroutines.sync.Semaphore -import kotlinx.coroutines.sync.withPermit import kotlinx.coroutines.withContext @HiltWorker @@ -78,33 +75,37 @@ class DownloadStatsWorker @AssistedInject constructor( val fileNames = ConcurrentLinkedQueue( generateMonthlyFileNames(lastModified) ) - val successfulResults = AtomicInt(0) - val updatedResults = AtomicInt(0) Log.d(TAG, "Fetching ${fileNames.size} monthly files") while (fileNames.isNotEmpty()) { - launch { - downloadSemaphores.withPermit { - val fileName = fileNames.poll() ?: return@withPermit - val target = Cache.getTemporaryFile(context) + if (downloadSemaphores.tryAcquire()) { + launch { + val fileName = fileNames.poll() + if (fileName == null) { + downloadSemaphores.release() + } else { + val target = Cache.getTemporaryFile(context) + try { + Log.i(TAG, "Downloading $fileName") + val response = downloadFile(fileName, target) + Log.i(TAG, "Downloaded $fileName with $response") - Log.i(TAG, "Downloading $fileName") - val response = downloadFile(fileName, target) - Log.i(TAG, "Downloaded $fileName with $response") - - if (response is NetworkResponse.Success) { - successfulResults.incrementAndFetch() - val isModified = response.statusCode != HttpStatusCode.NotModified.value - if (isModified) { - processDownloadStats( - response = response, - fileName = fileName, - target = target - ) - updatedResults.incrementAndFetch() + if (response is NetworkResponse.Success) { + val isModified = + response.statusCode != HttpStatusCode.NotModified.value + if (isModified) { + processDownloadStats( + response = response, + fileName = fileName, + target = target + ) + } + } + } finally { + target.delete() + downloadSemaphores.release() } } - target.delete() } } }