fix: priority tasks could be executed out of order

This commit is contained in:
Gauthier Roebroeck 2021-05-06 15:19:55 +08:00
parent 19e302b140
commit 55b288388f
4 changed files with 24 additions and 14 deletions

View file

@ -17,17 +17,25 @@ import org.gotson.komga.infrastructure.jms.QUEUE_UNIQUE_ID
import org.springframework.data.domain.Sort
import org.springframework.jms.core.JmsTemplate
import org.springframework.stereotype.Service
import javax.jms.ConnectionFactory
private val logger = KotlinLogging.logger {}
@Service
class TaskReceiver(
private val jmsTemplate: JmsTemplate,
private val connectionFactory: ConnectionFactory,
private val libraryRepository: LibraryRepository,
private val bookRepository: BookRepository,
private val bookConverter: BookConverter,
) {
private val jmsTemplates = (0..9).associateWith {
JmsTemplate(connectionFactory).apply {
priority = it
isExplicitQosEnabled = true
}
}
fun scanLibraries() {
libraryRepository.findAll().forEach { scanLibrary(it.id) }
}
@ -102,8 +110,7 @@ class TaskReceiver(
private fun submitTask(task: Task) {
logger.info { "Sending task: $task" }
jmsTemplate.priority = task.priority
jmsTemplate.convertAndSend(QUEUE_TASKS, task) {
jmsTemplates[task.priority]!!.convertAndSend(QUEUE_TASKS, task) {
it.apply {
setStringProperty(QUEUE_TYPE, QUEUE_TASKS_TYPE)
setStringProperty(QUEUE_UNIQUE_ID, task.uniqueId())

View file

@ -33,7 +33,6 @@ spring:
web:
resources:
add-mappings: false
jms.template.qos-enabled: true
server:
servlet.session.timeout: 7d

View file

@ -70,19 +70,21 @@ class TaskHandlerTest(
fun `when high priority tasks are submitted then they are executed first`() {
val slot = slot<String>()
val calls = mutableListOf<Book>()
every { mockBookRepository.findByIdOrNull(capture(slot)) } answers { makeBook(slot.captured) }
every { mockBookRepository.findByIdOrNull(capture(slot)) } answers {
Thread.sleep(1_00)
makeBook(slot.captured)
}
every { mockBookLifecycle.analyzeAndPersist(capture(calls)) } returns false
jmsListenerEndpointRegistry.stop()
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)
taskReceiver.analyzeBook("1")
taskReceiver.analyzeBook("2", HIGH_PRIORITY)
Thread.sleep(1_000)
jmsListenerEndpointRegistry.start()
Thread.sleep(1_00)
verify(exactly = 2) { mockBookLifecycle.analyzeAndPersist(any()) }
assertThat(calls.map { it.name }).containsExactly("2", "1")
verify(exactly = 5) { mockBookLifecycle.analyzeAndPersist(any()) }
assertThat(calls.map { it.name }).containsExactly("1", "4", "3", "5", "2")
}
}

View file

@ -97,6 +97,7 @@ class ArtemisConfigTest(
fun `when sending messages with different priority then high priority messages are received first`() {
for (i in 0..9) {
jmsTemplate.priority = i
jmsTemplate.isExplicitQosEnabled = true
jmsTemplate.convertAndSend(
QUEUE_TASKS,
"message A $i"
@ -105,6 +106,7 @@ class ArtemisConfigTest(
for (i in 9 downTo 0) {
jmsTemplate.priority = i
jmsTemplate.isExplicitQosEnabled = true
jmsTemplate.convertAndSend(
QUEUE_TASKS,
"message B $i"