Fix tracker operations parallelism

This commit is contained in:
Koitharu
2023-09-05 10:29:51 +03:00
parent d1b0af85c4
commit d3e4e97c6f
3 changed files with 49 additions and 21 deletions

View File

@@ -110,21 +110,26 @@ class Tracker @Inject constructor(
private fun compare(track: MangaTracking, manga: Manga, branch: String?): MangaUpdates.Success {
if (track.isEmpty()) {
// first check or manga was empty on last check
return MangaUpdates.Success(manga, emptyList(), isValid = false)
return MangaUpdates.Success(manga, emptyList(), isValid = false, channelId = null)
}
val chapters = requireNotNull(manga.getChapters(branch))
val newChapters = chapters.takeLastWhile { x -> x.id != track.lastChapterId }
return when {
newChapters.isEmpty() -> {
MangaUpdates.Success(manga, emptyList(), isValid = chapters.lastOrNull()?.id == track.lastChapterId)
MangaUpdates.Success(
manga = manga,
newChapters = emptyList(),
isValid = chapters.lastOrNull()?.id == track.lastChapterId,
channelId = null
)
}
newChapters.size == chapters.size -> {
MangaUpdates.Success(manga, emptyList(), isValid = false)
MangaUpdates.Success(manga, emptyList(), isValid = false, channelId = null)
}
else -> {
MangaUpdates.Success(manga, newChapters, isValid = true)
MangaUpdates.Success(manga, newChapters, isValid = true, channelId = null)
}
}
}

View File

@@ -8,16 +8,17 @@ sealed interface MangaUpdates {
val manga: Manga
class Success(
data class Success(
override val manga: Manga,
val newChapters: List<MangaChapter>,
val isValid: Boolean,
val channelId: String?,
) : MangaUpdates {
fun isNotEmpty() = newChapters.isNotEmpty()
}
class Failure(
data class Failure(
override val manga: Manga,
val error: Throwable?,
) : MangaUpdates {

View File

@@ -39,6 +39,7 @@ import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.launch
import kotlinx.coroutines.runInterruptible
@@ -148,19 +149,9 @@ class TrackWorker @AssistedInject constructor(
send(
runCatchingCancellable {
tracker.fetchUpdates(track, commit = true)
.copy(channelId = channelId)
}.onFailure { e ->
if (e is CloudFlareProtectedException) {
CaptchaNotifier(applicationContext).notify(e)
}
logger.log("checkUpdatesAsync", e)
}.onSuccess { updates ->
if (updates.isValid && updates.isNotEmpty()) {
showNotification(
manga = updates.manga,
channelId = channelId,
newChapters = updates.newChapters,
)
}
}.getOrElse { error ->
MangaUpdates.Failure(
manga = track.manga,
@@ -171,10 +162,33 @@ class TrackWorker @AssistedInject constructor(
}
}
}
}.onEach {
when (it) {
is MangaUpdates.Failure -> {
val e = it.error
if (e is CloudFlareProtectedException) {
CaptchaNotifier(applicationContext).notify(e)
}
}
is MangaUpdates.Success -> {
if (it.isValid && it.isNotEmpty()) {
showNotification(
manga = it.manga,
channelId = it.channelId,
newChapters = it.newChapters,
)
}
}
}
}.toList(ArrayList(tracks.size))
}
private suspend fun showNotification(manga: Manga, channelId: String?, newChapters: List<MangaChapter>) {
private suspend fun showNotification(
manga: Manga,
channelId: String?,
newChapters: List<MangaChapter>,
) {
if (newChapters.isEmpty() || channelId == null || !applicationContext.checkNotificationPermission()) {
return
}
@@ -239,7 +253,10 @@ class TrackWorker @AssistedInject constructor(
override suspend fun getForegroundInfo(): ForegroundInfo {
val title = applicationContext.getString(R.string.check_for_new_chapters)
val channel = NotificationChannelCompat.Builder(WORKER_CHANNEL_ID, NotificationManagerCompat.IMPORTANCE_LOW)
val channel = NotificationChannelCompat.Builder(
WORKER_CHANNEL_ID,
NotificationManagerCompat.IMPORTANCE_LOW
)
.setName(title)
.setShowBadge(false)
.setVibrationEnabled(false)
@@ -260,7 +277,11 @@ class TrackWorker @AssistedInject constructor(
.setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_DEFERRED)
.build()
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ForegroundInfo(WORKER_NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
ForegroundInfo(
WORKER_NOTIFICATION_ID,
notification,
ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
)
} else {
ForegroundInfo(WORKER_NOTIFICATION_ID, notification)
}
@@ -320,7 +341,8 @@ class TrackWorker @AssistedInject constructor(
}
fun startNow() {
val constraints = Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()
val constraints =
Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()
val request = OneTimeWorkRequestBuilder<TrackWorker>()
.setConstraints(constraints)
.addTag(TAG_ONESHOT)