refactor: update RabbitMQ queue configurations and improve content sorting

This commit is contained in:
Rodrigo Verdiani 2026-03-25 07:58:01 -03:00
parent d11290c28a
commit 6d432ee29f
6 changed files with 109 additions and 15 deletions

View File

@ -16,6 +16,8 @@ public class MangaUpdateConsumer {
@RabbitListener(queues = "${queues.manga-update}") @RabbitListener(queues = "${queues.manga-update}")
public void receiveMangaUpdateCommand(MangaUpdateCommand command) { public void receiveMangaUpdateCommand(MangaUpdateCommand command) {
log.info("Received manga update command: {}", command); log.info("Received manga update command: {}", command);
mangaUpdateService.update(command.mangaId()); throw new RuntimeException("teste");
// mangaUpdateService.update(command.mangaId());
} }
} }

View File

@ -3,6 +3,7 @@ package com.magamochi.common.config;
import com.magamochi.common.model.enumeration.ContentType; import com.magamochi.common.model.enumeration.ContentType;
import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.Queue; import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.amqp.core.TopicExchange; import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.rabbit.core.RabbitTemplate;
@ -53,27 +54,67 @@ public class RabbitConfig {
@Bean @Bean
public Queue imageFetchQueue() { public Queue imageFetchQueue() {
return new Queue(imageFetchQueue, false); return QueueBuilder.nonDurable(imageFetchQueue)
.deadLetterExchange("")
.deadLetterRoutingKey(imageFetchQueue + ".dlq")
.build();
}
@Bean
public Queue imageFetchDlq() {
return QueueBuilder.nonDurable(imageFetchQueue + ".dlq").build();
} }
@Bean @Bean
public Queue mangaUpdateQueue() { public Queue mangaUpdateQueue() {
return new Queue(mangaUpdateQueue, false); return QueueBuilder.nonDurable(mangaUpdateQueue)
.deadLetterExchange("")
.deadLetterRoutingKey(mangaUpdateQueue + ".dlq")
.build();
}
@Bean
public Queue mangaUpdateDlq() {
return QueueBuilder.nonDurable(mangaUpdateQueue + ".dlq").build();
} }
@Bean @Bean
public Queue mangaContentImageUpdateQueue() { public Queue mangaContentImageUpdateQueue() {
return new Queue(mangaContentImageUpdateQueue, false); return QueueBuilder.nonDurable(mangaContentImageUpdateQueue)
.deadLetterExchange("")
.deadLetterRoutingKey(mangaContentImageUpdateQueue + ".dlq")
.build();
}
@Bean
public Queue mangaContentImageUpdateDlq() {
return QueueBuilder.nonDurable(mangaContentImageUpdateQueue + ".dlq").build();
} }
@Bean @Bean
public Queue mangaCoverUpdateQueue() { public Queue mangaCoverUpdateQueue() {
return new Queue(mangaCoverUpdateQueue, false); return QueueBuilder.nonDurable(mangaCoverUpdateQueue)
.deadLetterExchange("")
.deadLetterRoutingKey(mangaCoverUpdateQueue + ".dlq")
.build();
}
@Bean
public Queue mangaCoverUpdateDlq() {
return QueueBuilder.nonDurable(mangaCoverUpdateQueue + ".dlq").build();
} }
@Bean @Bean
public Queue fileImportQueue() { public Queue fileImportQueue() {
return new Queue(fileImportQueue, false); return QueueBuilder.nonDurable(fileImportQueue)
.deadLetterExchange("")
.deadLetterRoutingKey(fileImportQueue + ".dlq")
.build();
}
@Bean
public Queue fileImportDlq() {
return QueueBuilder.nonDurable(fileImportQueue + ".dlq").build();
} }
@Bean @Bean
@ -101,22 +142,54 @@ public class RabbitConfig {
@Bean @Bean
public Queue mangaContentIngestQueue() { public Queue mangaContentIngestQueue() {
return new Queue(mangaContentIngestQueue, false); return QueueBuilder.nonDurable(mangaContentIngestQueue)
.deadLetterExchange("")
.deadLetterRoutingKey(mangaContentIngestQueue + ".dlq")
.build();
}
@Bean
public Queue mangaContentIngestDlq() {
return QueueBuilder.nonDurable(mangaContentIngestQueue + ".dlq").build();
} }
@Bean @Bean
public Queue mangaContentImageIngestQueue() { public Queue mangaContentImageIngestQueue() {
return new Queue(mangaContentImageIngestQueue, false); return QueueBuilder.nonDurable(mangaContentImageIngestQueue)
.deadLetterExchange("")
.deadLetterRoutingKey(mangaContentImageIngestQueue + ".dlq")
.build();
}
@Bean
public Queue mangaContentImageIngestDlq() {
return QueueBuilder.nonDurable(mangaContentImageIngestQueue + ".dlq").build();
} }
@Bean @Bean
public Queue mangaIngestQueue() { public Queue mangaIngestQueue() {
return new Queue(mangaIngestQueue, false); return QueueBuilder.nonDurable(mangaIngestQueue)
.deadLetterExchange("")
.deadLetterRoutingKey(mangaIngestQueue + ".dlq")
.build();
}
@Bean
public Queue mangaIngestDlq() {
return QueueBuilder.nonDurable(mangaIngestQueue + ".dlq").build();
} }
@Bean @Bean
public Queue providerPageIngestQueue() { public Queue providerPageIngestQueue() {
return new Queue(providerPageIngestQueue, false); return QueueBuilder.nonDurable(providerPageIngestQueue)
.deadLetterExchange("")
.deadLetterRoutingKey(providerPageIngestQueue + ".dlq")
.build();
}
@Bean
public Queue providerPageIngestDlq() {
return QueueBuilder.nonDurable(providerPageIngestQueue + ".dlq").build();
} }
// TODO: remove unused queues // TODO: remove unused queues
@ -129,12 +202,28 @@ public class RabbitConfig {
@Bean @Bean
public Queue mangaChapterDownloadQueue() { public Queue mangaChapterDownloadQueue() {
return new Queue(mangaChapterDownloadQueue, false); return QueueBuilder.nonDurable(mangaChapterDownloadQueue)
.deadLetterExchange("")
.deadLetterRoutingKey(mangaChapterDownloadQueue + ".dlq")
.build();
}
@Bean
public Queue mangaChapterDownloadDlq() {
return QueueBuilder.nonDurable(mangaChapterDownloadQueue + ".dlq").build();
} }
@Bean @Bean
public Queue mangaFollowUpdateChapterQueue() { public Queue mangaFollowUpdateChapterQueue() {
return new Queue(mangaFollowUpdateChapterQueue, false); return QueueBuilder.nonDurable(mangaFollowUpdateChapterQueue)
.deadLetterExchange("")
.deadLetterRoutingKey(mangaFollowUpdateChapterQueue + ".dlq")
.build();
}
@Bean
public Queue mangaFollowUpdateChapterDlq() {
return QueueBuilder.nonDurable(mangaFollowUpdateChapterQueue + ".dlq").build();
} }
@Bean @Bean

View File

@ -8,5 +8,5 @@ import org.springframework.stereotype.Repository;
@Repository @Repository
public interface MangaImportJobRepository extends JpaRepository<MangaImportJob, Long> { public interface MangaImportJobRepository extends JpaRepository<MangaImportJob, Long> {
List<MangaImportJob> findByStatus(ImportJobStatus status); List<MangaImportJob> findByStatusOrderByIdAsc(ImportJobStatus importJobStatus);
} }

View File

@ -25,7 +25,7 @@ public class ContentService {
var mangaContentProvider = mangaContentProviderService.find(mangaContentProviderId); var mangaContentProvider = mangaContentProviderService.find(mangaContentProviderId);
return mangaContentProvider.getMangaContents().stream() return mangaContentProvider.getMangaContents().stream()
.sorted(Comparator.comparing(MangaContent::getId)) .sorted(Comparator.comparing(MangaContent::getTitle))
.map( .map(
mangaContent -> { mangaContent -> {
var isRead = userMangaContentReadService.isRead(mangaContent.getId()); var isRead = userMangaContentReadService.isRead(mangaContent.getId());

View File

@ -26,7 +26,7 @@ public class PendingImportScannerTask {
@Scheduled(fixedDelayString = "${tasks.pending-import-scanner.delay:30000}") @Scheduled(fixedDelayString = "${tasks.pending-import-scanner.delay:30000}")
public void scanPendingImports() { public void scanPendingImports() {
var pendingJobs = mangaImportJobRepository.findByStatus(ImportJobStatus.PENDING); var pendingJobs = mangaImportJobRepository.findByStatusOrderByIdAsc(ImportJobStatus.PENDING);
for (var job : pendingJobs) { for (var job : pendingJobs) {
if (!s3Service.objectExists(job.getS3FileKey())) { if (!s3Service.objectExists(job.getS3FileKey())) {

View File

@ -30,6 +30,9 @@ spring:
port: ${RABBITMQ_PORT} port: ${RABBITMQ_PORT}
username: ${RABBITMQ_USERNAME} username: ${RABBITMQ_USERNAME}
password: ${RABBITMQ_PASSWORD} password: ${RABBITMQ_PASSWORD}
listener:
simple:
default-requeue-rejected: false
springdoc: springdoc:
api-docs: api-docs: