From 7ec18861bfbca5dafc006890a64443611bdfc333 Mon Sep 17 00:00:00 2001 From: NerdNumber9 Date: Fri, 2 Aug 2019 22:54:06 -0400 Subject: [PATCH] Use semaphores instead of channels where possible Use correct starting title in auto-migrator --- .../process/MigrationProcedureController.kt | 70 +++++++++---------- 1 file changed, 33 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/exh/ui/migration/manga/process/MigrationProcedureController.kt b/app/src/main/java/exh/ui/migration/manga/process/MigrationProcedureController.kt index badeecb80..6d1c67b7b 100644 --- a/app/src/main/java/exh/ui/migration/manga/process/MigrationProcedureController.kt +++ b/app/src/main/java/exh/ui/migration/manga/process/MigrationProcedureController.kt @@ -16,14 +16,16 @@ import exh.ui.base.BaseExhController import exh.util.await import kotlinx.android.synthetic.main.eh_migration_process.* import kotlinx.coroutines.* -import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.sync.Semaphore +import kotlinx.coroutines.sync.withPermit import rx.schedulers.Schedulers import uy.kohesive.injekt.injectLazy +import java.util.concurrent.atomic.AtomicInteger class MigrationProcedureController(bundle: Bundle? = null) : BaseExhController(bundle), CoroutineScope { override val layoutId = R.layout.eh_migration_process - private var titleText = "Migrate manga (1/300)" + private var titleText = "Migrate manga" private var adapter: MigrationProcedureAdapter? = null @@ -108,42 +110,36 @@ class MigrationProcedureController(bundle: Bundle? = null) : BaseExhController(b it.id != mangaSource.id } if(config.useSourceWithMostChapters) { - val sourceQueue = Channel(Channel.RENDEZVOUS) - launch { - validSources.forEachIndexed { index, catalogueSource -> - sourceQueue.send(catalogueSource) - manga.progress.send(validSources.size to index) + val sourceSemaphore = Semaphore(3) + val processedSources = AtomicInteger() + + validSources.map { source -> + async { + sourceSemaphore.withPermit { + try { + supervisorScope { + val searchResult = if (config.enableLenientSearch) { + smartSearchEngine.smartSearch(source, mangaObj.title) + } else { + smartSearchEngine.normalSearch(source, mangaObj.title) + } + + if(searchResult != null) { + val localManga = smartSearchEngine.networkToLocalManga(searchResult, source.id) + val chapters = source.fetchChapterList(localManga).toSingle().await(Schedulers.io()) + manga.progress.send(validSources.size to processedSources.incrementAndGet()) + localManga to chapters.size + } else { + null + } + } + } catch(e: Exception) { + logger.e("Failed to search in source: ${source.id}!", e) + null + } + } } - sourceQueue.close() - } - - val results = mutableListOf>() - - (1 .. 3).map { - launch { - for(source in sourceQueue) { - try { - supervisorScope { - val searchResult = if (config.enableLenientSearch) { - smartSearchEngine.smartSearch(source, mangaObj.title) - } else { - smartSearchEngine.normalSearch(source, mangaObj.title) - } - - if(searchResult != null) { - val localManga = smartSearchEngine.networkToLocalManga(searchResult, source.id) - val chapters = source.fetchChapterList(localManga).toSingle().await(Schedulers.io()) - results += localManga to chapters.size - } - } - } catch(e: Exception) { - logger.e("Failed to search in source: ${source.id}!", e) - } - } - } - }.forEach { it.join() } - - results.maxBy { it.second }?.first + }.mapNotNull { it.await() }.maxBy { it.second }?.first } else { validSources.forEachIndexed { index, source -> val searchResult = try {