mirror of
https://github.com/gotson/komga.git
synced 2025-12-20 23:45:11 +01:00
fix: some tasks could be executed with the wrong priority
This commit is contained in:
parent
5fc77b2297
commit
2b6f534f84
4 changed files with 54 additions and 19 deletions
|
|
@ -32,12 +32,14 @@ sealed class Task(priority: Int = DEFAULT_PRIORITY) : Serializable {
|
|||
override fun toString(): String = "RefreshBookMetadata(bookId='$bookId', capabilities=$capabilities, priority='$priority')"
|
||||
}
|
||||
|
||||
data class RefreshSeriesMetadata(val seriesId: String) : Task() {
|
||||
class RefreshSeriesMetadata(val seriesId: String, priority: Int = DEFAULT_PRIORITY) : Task(priority) {
|
||||
override fun uniqueId() = "REFRESH_SERIES_METADATA_$seriesId"
|
||||
override fun toString(): String = "RefreshSeriesMetadata(seriesId='$seriesId', priority='$priority')"
|
||||
}
|
||||
|
||||
data class AggregateSeriesMetadata(val seriesId: String) : Task() {
|
||||
class AggregateSeriesMetadata(val seriesId: String, priority: Int = DEFAULT_PRIORITY) : Task(priority) {
|
||||
override fun uniqueId() = "AGGREGATE_SERIES_METADATA_$seriesId"
|
||||
override fun toString(): String = "AggregateSeriesMetadata(seriesId='$seriesId', priority='$priority')"
|
||||
}
|
||||
|
||||
class RefreshBookLocalArtwork(val bookId: String, priority: Int = DEFAULT_PRIORITY) : Task(priority) {
|
||||
|
|
|
|||
|
|
@ -64,13 +64,13 @@ class TaskHandler(
|
|||
is Task.RefreshBookMetadata ->
|
||||
bookRepository.findByIdOrNull(task.bookId)?.let { book ->
|
||||
metadataLifecycle.refreshMetadata(book, task.capabilities)
|
||||
taskReceiver.refreshSeriesMetadata(book.seriesId)
|
||||
taskReceiver.refreshSeriesMetadata(book.seriesId, priority = task.priority - 1)
|
||||
} ?: logger.warn { "Cannot execute task $task: Book does not exist" }
|
||||
|
||||
is Task.RefreshSeriesMetadata ->
|
||||
seriesRepository.findByIdOrNull(task.seriesId)?.let { series ->
|
||||
metadataLifecycle.refreshMetadata(series)
|
||||
taskReceiver.aggregateSeriesMetadata(series.id)
|
||||
taskReceiver.aggregateSeriesMetadata(series.id, priority = task.priority)
|
||||
} ?: logger.warn { "Cannot execute task $task: Series does not exist" }
|
||||
|
||||
is Task.AggregateSeriesMetadata ->
|
||||
|
|
|
|||
|
|
@ -83,12 +83,12 @@ class TaskReceiver(
|
|||
submitTask(Task.RefreshBookMetadata(bookId, capabilities, priority))
|
||||
}
|
||||
|
||||
fun refreshSeriesMetadata(seriesId: String) {
|
||||
submitTask(Task.RefreshSeriesMetadata(seriesId))
|
||||
fun refreshSeriesMetadata(seriesId: String, priority: Int = DEFAULT_PRIORITY) {
|
||||
submitTask(Task.RefreshSeriesMetadata(seriesId, priority))
|
||||
}
|
||||
|
||||
fun aggregateSeriesMetadata(seriesId: String) {
|
||||
submitTask(Task.AggregateSeriesMetadata(seriesId))
|
||||
fun aggregateSeriesMetadata(seriesId: String, priority: Int = DEFAULT_PRIORITY) {
|
||||
submitTask(Task.AggregateSeriesMetadata(seriesId, priority))
|
||||
}
|
||||
|
||||
fun refreshBookLocalArtwork(bookId: String, priority: Int = DEFAULT_PRIORITY) {
|
||||
|
|
|
|||
|
|
@ -2,14 +2,20 @@ package org.gotson.komga.application.tasks
|
|||
|
||||
import com.ninjasquad.springmockk.MockkBean
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.runs
|
||||
import io.mockk.slot
|
||||
import io.mockk.verify
|
||||
import mu.KotlinLogging
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.gotson.komga.domain.model.Book
|
||||
import org.gotson.komga.domain.model.Series
|
||||
import org.gotson.komga.domain.model.makeBook
|
||||
import org.gotson.komga.domain.model.makeSeries
|
||||
import org.gotson.komga.domain.persistence.BookRepository
|
||||
import org.gotson.komga.domain.persistence.SeriesRepository
|
||||
import org.gotson.komga.domain.service.BookLifecycle
|
||||
import org.gotson.komga.domain.service.MetadataLifecycle
|
||||
import org.gotson.komga.infrastructure.jms.QUEUE_TASKS
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Test
|
||||
|
|
@ -34,6 +40,12 @@ class TaskHandlerTest(
|
|||
@MockkBean
|
||||
private lateinit var mockBookLifecycle: BookLifecycle
|
||||
|
||||
@MockkBean
|
||||
private lateinit var mockMetadataLifecycle: MetadataLifecycle
|
||||
|
||||
@MockkBean
|
||||
private lateinit var mockSeriesRepository: SeriesRepository
|
||||
|
||||
@MockkBean
|
||||
private lateinit var mockBookRepository: BookRepository
|
||||
|
||||
|
|
@ -49,16 +61,14 @@ class TaskHandlerTest(
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `when similar tasks are submitted then only a few are executed`() {
|
||||
fun `when similar tasks are submitted then only one is executed`() {
|
||||
every { mockBookRepository.findByIdOrNull(any()) } returns makeBook("id")
|
||||
every { mockBookLifecycle.analyzeAndPersist(any()) } returns false
|
||||
|
||||
jmsListenerEndpointRegistry.stop()
|
||||
|
||||
repeat(100) {
|
||||
taskReceiver.analyzeBook("id")
|
||||
}
|
||||
|
||||
jmsListenerEndpointRegistry.start()
|
||||
|
||||
Thread.sleep(1_00)
|
||||
|
|
@ -76,15 +86,38 @@ class TaskHandlerTest(
|
|||
}
|
||||
every { mockBookLifecycle.analyzeAndPersist(capture(calls)) } returns false
|
||||
|
||||
taskReceiver.analyzeBook("1", HIGHEST_PRIORITY)
|
||||
taskReceiver.analyzeBook("2", LOWEST_PRIORITY)
|
||||
taskReceiver.analyzeBook("3", HIGH_PRIORITY)
|
||||
taskReceiver.analyzeBook("4", HIGHEST_PRIORITY)
|
||||
taskReceiver.analyzeBook("5", DEFAULT_PRIORITY)
|
||||
jmsListenerEndpointRegistry.stop()
|
||||
(0..9).forEach {
|
||||
taskReceiver.analyzeBook("$it", it)
|
||||
}
|
||||
jmsListenerEndpointRegistry.start()
|
||||
|
||||
Thread.sleep(1_000)
|
||||
Thread.sleep(3_000)
|
||||
|
||||
verify(exactly = 5) { mockBookLifecycle.analyzeAndPersist(any()) }
|
||||
assertThat(calls.map { it.name }).containsExactly("1", "4", "3", "5", "2")
|
||||
verify(exactly = 10) { mockBookLifecycle.analyzeAndPersist(any()) }
|
||||
assertThat(calls.map { it.name }).containsExactlyElementsOf((9 downTo 0).map { "$it" })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when high priority tasks triggering tasks are submitted then they are executed first`() {
|
||||
val slot = slot<String>()
|
||||
val calls = mutableListOf<Series>()
|
||||
every { mockSeriesRepository.findByIdOrNull(capture(slot)) } answers {
|
||||
Thread.sleep(1_00)
|
||||
makeSeries(slot.captured)
|
||||
}
|
||||
every { mockMetadataLifecycle.refreshMetadata(capture(calls)) } just runs
|
||||
every { mockMetadataLifecycle.aggregateMetadata(any()) } just runs
|
||||
|
||||
jmsListenerEndpointRegistry.stop()
|
||||
(0..9).forEach {
|
||||
taskReceiver.refreshSeriesMetadata("$it", it)
|
||||
}
|
||||
jmsListenerEndpointRegistry.start()
|
||||
|
||||
Thread.sleep(5_000)
|
||||
|
||||
verify(exactly = 10) { mockMetadataLifecycle.refreshMetadata(any()) }
|
||||
assertThat(calls.map { it.name }).containsExactlyElementsOf((9 downTo 0).map { "$it" })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue