mirror of
https://github.com/gotson/komga.git
synced 2026-01-04 14:52:51 +01:00
added async management for book parsing
This commit is contained in:
parent
1c298221f8
commit
cb867ff519
4 changed files with 39 additions and 8 deletions
|
|
@ -6,8 +6,11 @@ import org.gotson.komga.domain.model.Book
|
|||
import org.gotson.komga.domain.model.BookMetadata
|
||||
import org.gotson.komga.domain.model.Status
|
||||
import org.gotson.komga.domain.persistence.BookRepository
|
||||
import org.springframework.scheduling.annotation.Async
|
||||
import org.springframework.scheduling.annotation.AsyncResult
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.util.concurrent.Future
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
|
@ -19,9 +22,10 @@ class BookManager(
|
|||
) {
|
||||
|
||||
@Transactional
|
||||
fun parseAndPersist(book: Book) {
|
||||
@Async("parseBookTaskExecutor")
|
||||
fun parseAndPersist(book: Book): Future<Long> {
|
||||
logger.info { "Parse and persist book: ${book.url}" }
|
||||
measureTimeMillis {
|
||||
return AsyncResult(measureTimeMillis {
|
||||
try {
|
||||
book.metadata = bookParser.parse(book)
|
||||
} catch (ex: UnsupportedMediaTypeException) {
|
||||
|
|
@ -32,7 +36,7 @@ class BookManager(
|
|||
book.metadata = BookMetadata(status = Status.ERROR)
|
||||
}
|
||||
bookRepository.save(book)
|
||||
}.also { logger.info { "Parsing finished in ${DurationFormatUtils.formatDurationHMS(it)}" } }
|
||||
}.also { logger.info { "Parsing finished in ${DurationFormatUtils.formatDurationHMS(it)}" } })
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -80,10 +80,17 @@ class LibraryManager(
|
|||
}
|
||||
|
||||
fun parseUnparsedBooks() {
|
||||
logger.info { "Parsing all books in status: unkown" }
|
||||
logger.info { "Parsing all books in status: unknown" }
|
||||
val booksToParse = bookRepository.findAllByMetadataStatus(Status.UNKNOWN)
|
||||
|
||||
var sumOfTasksTime = 0L
|
||||
measureTimeMillis {
|
||||
booksToParse.forEach { bookManager.parseAndPersist(it) }
|
||||
}.also { logger.info { "Parsed ${booksToParse.size} books in ${DurationFormatUtils.formatDurationHMS(it)}" } }
|
||||
sumOfTasksTime = booksToParse
|
||||
.map { bookManager.parseAndPersist(it) }
|
||||
.map { it.get() }
|
||||
.sum()
|
||||
}.also {
|
||||
logger.info { "Parsed ${booksToParse.size} books in ${DurationFormatUtils.formatDurationHMS(it)} (virtual: ${DurationFormatUtils.formatDurationHMS(sumOfTasksTime)})" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package org.gotson.komga.infrastructure.async
|
||||
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.scheduling.annotation.EnableAsync
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
|
||||
import java.util.concurrent.Executor
|
||||
|
||||
@Configuration
|
||||
@EnableAsync
|
||||
class AsyncConfiguration {
|
||||
|
||||
@Bean
|
||||
fun parseBookTaskExecutor(): Executor =
|
||||
ThreadPoolTaskExecutor().apply {
|
||||
corePoolSize = 5
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,6 @@ import javax.persistence.EntityManager
|
|||
@ExtendWith(SpringExtension::class)
|
||||
@SpringBootTest
|
||||
@AutoConfigureTestDatabase
|
||||
@Transactional
|
||||
class LibraryManagerTest(
|
||||
@Autowired private val serieRepository: SerieRepository,
|
||||
@Autowired private val bookRepository: BookRepository,
|
||||
|
|
@ -48,6 +47,7 @@ class LibraryManagerTest(
|
|||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
fun `given existing Serie when adding files and scanning then only updated Books are persisted`() {
|
||||
//given
|
||||
val serie = makeSerie(name = "serie", books = listOf(makeBook("book1")))
|
||||
|
|
@ -73,6 +73,7 @@ class LibraryManagerTest(
|
|||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
fun `given existing Serie when removing files and scanning then only updated Books are persisted`() {
|
||||
//given
|
||||
val serie = makeSerie(name = "serie", books = listOf(makeBook("book1"), makeBook("book2")))
|
||||
|
|
@ -100,6 +101,7 @@ class LibraryManagerTest(
|
|||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
fun `given existing Serie when updating files and scanning then Books are updated`() {
|
||||
//given
|
||||
val serie = makeSerie(name = "serie", books = listOf(makeBook("book1")))
|
||||
|
|
@ -161,7 +163,7 @@ class LibraryManagerTest(
|
|||
libraryManager.scanRootFolder(library)
|
||||
|
||||
every { mockParser.parse(any()) } returns BookMetadata(status = Status.READY, mediaType = "application/zip", pages = mutableListOf(makeBookPage("1.jpg"), makeBookPage("2.jpg")))
|
||||
bookRepository.findAll().forEach { bookManager.parseAndPersist(it) }
|
||||
bookRepository.findAll().map { bookManager.parseAndPersist(it) }.map { it.get() }
|
||||
|
||||
// when
|
||||
libraryManager.scanRootFolder(library)
|
||||
|
|
|
|||
Loading…
Reference in a new issue