Merge pull request 'feat(manga): enhance ingest process with error handling' (#64) from feat/concurrency into main
Reviewed-on: #64
This commit is contained in:
commit
3b8a8f87e2
@ -27,6 +27,20 @@ public class MangaIngestService {
|
||||
log.info(
|
||||
"Ingesting manga with mangaTitle '{}' from provider {}", mangaTitle, contentProviderId);
|
||||
|
||||
try {
|
||||
doIngestManga(contentProviderId, mangaTitle, url);
|
||||
} catch (Exception e) {
|
||||
log.error(
|
||||
"Unexpected error ingesting manga '{}' from provider {} at url '{}'",
|
||||
mangaTitle,
|
||||
contentProviderId,
|
||||
url,
|
||||
e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private void doIngestManga(long contentProviderId, String mangaTitle, String url) {
|
||||
if (mangaContentProviderRepository.existsByMangaTitleIgnoreCaseAndContentProvider_Id(
|
||||
mangaTitle, contentProviderId)) {
|
||||
log.info(
|
||||
@ -51,6 +65,17 @@ public class MangaIngestService {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mangaContentProviderRepository
|
||||
.findByManga_IdAndContentProvider_Id(manga.getId(), contentProviderId)
|
||||
.isPresent()) {
|
||||
log.info(
|
||||
"MangaContentProvider already exists for manga '{}' (ID: {}) and provider '{}', skipping ingest",
|
||||
manga.getTitle(),
|
||||
manga.getId(),
|
||||
contentProviderId);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var contentProvider = contentProviderService.find(contentProviderId);
|
||||
|
||||
@ -63,10 +88,11 @@ public class MangaIngestService {
|
||||
.build());
|
||||
} catch (Exception e) {
|
||||
log.error(
|
||||
"Failed to ingest manga with mangaTitle '{}' from provider '{}'",
|
||||
"Failed to save manga content provider for manga '{}' from provider '{}'",
|
||||
mangaTitle,
|
||||
contentProviderId,
|
||||
e);
|
||||
return;
|
||||
}
|
||||
|
||||
log.info(
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.magamochi.catalog.service;
|
||||
|
||||
import static java.util.Objects.isNull;
|
||||
import static java.util.Objects.nonNull;
|
||||
|
||||
import com.magamochi.catalog.model.entity.Manga;
|
||||
@ -9,6 +10,7 @@ import com.magamochi.catalog.queue.producer.MangaUpdateProducer;
|
||||
import java.util.Optional;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Log4j2
|
||||
@ -116,21 +118,21 @@ public class MangaResolutionService {
|
||||
if (nonNull(aniListId)) {
|
||||
var existingByAniList = mangaRepository.findByAniListId(aniListId);
|
||||
if (existingByAniList.isPresent()) {
|
||||
return existingByAniList.get();
|
||||
return mergeExternalIds(existingByAniList.get(), canonicalTitle, aniListId, malId);
|
||||
}
|
||||
}
|
||||
|
||||
if (nonNull(malId)) {
|
||||
var existingByMalId = mangaRepository.findByMalId(malId);
|
||||
if (existingByMalId.isPresent()) {
|
||||
return existingByMalId.get();
|
||||
return mergeExternalIds(existingByMalId.get(), canonicalTitle, aniListId, malId);
|
||||
}
|
||||
}
|
||||
|
||||
if (nonNull(canonicalTitle)) {
|
||||
var existingByTitle = mangaRepository.findByTitleIgnoreCase(canonicalTitle);
|
||||
if (existingByTitle.isPresent()) {
|
||||
return existingByTitle.get();
|
||||
return mergeExternalIds(existingByTitle.get(), canonicalTitle, aniListId, malId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,13 +140,75 @@ public class MangaResolutionService {
|
||||
}
|
||||
|
||||
private Manga createAndNotifyManga(String title, Long aniListId, Long malId) {
|
||||
var manga =
|
||||
mangaRepository.save(
|
||||
Manga.builder().title(title).aniListId(aniListId).malId(malId).build());
|
||||
try {
|
||||
var manga =
|
||||
mangaRepository.save(
|
||||
Manga.builder().title(title).aniListId(aniListId).malId(malId).build());
|
||||
|
||||
mangaUpdateProducer.sendMangaUpdateCommand(new MangaUpdateCommand(manga.getId()));
|
||||
try {
|
||||
mangaUpdateProducer.sendMangaUpdateCommand(new MangaUpdateCommand(manga.getId()));
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to send manga update command for manga '{}' (ID: {})", title, manga.getId(), e);
|
||||
}
|
||||
|
||||
return manga;
|
||||
return manga;
|
||||
} catch (DataIntegrityViolationException e) {
|
||||
log.warn(
|
||||
"Race condition while creating manga '{}' (aniListId={}, malId={}), re-querying existing",
|
||||
title,
|
||||
aniListId,
|
||||
malId);
|
||||
|
||||
if (nonNull(aniListId)) {
|
||||
var existing = mangaRepository.findByAniListId(aniListId);
|
||||
if (existing.isPresent()) {
|
||||
return mergeExternalIds(existing.get(), title, aniListId, malId);
|
||||
}
|
||||
}
|
||||
if (nonNull(malId)) {
|
||||
var existing = mangaRepository.findByMalId(malId);
|
||||
if (existing.isPresent()) {
|
||||
return mergeExternalIds(existing.get(), title, aniListId, malId);
|
||||
}
|
||||
}
|
||||
if (nonNull(title)) {
|
||||
var existing = mangaRepository.findByTitleIgnoreCase(title);
|
||||
if (existing.isPresent()) {
|
||||
return mergeExternalIds(existing.get(), title, aniListId, malId);
|
||||
}
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private Manga mergeExternalIds(Manga existing, String canonicalTitle, Long aniListId, Long malId) {
|
||||
boolean updated = false;
|
||||
|
||||
if (isNull(existing.getAniListId()) && nonNull(aniListId)) {
|
||||
existing.setAniListId(aniListId);
|
||||
updated = true;
|
||||
}
|
||||
if (isNull(existing.getMalId()) && nonNull(malId)) {
|
||||
existing.setMalId(malId);
|
||||
updated = true;
|
||||
}
|
||||
if (isNull(existing.getTitle()) && nonNull(canonicalTitle)) {
|
||||
existing.setTitle(canonicalTitle);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (updated) {
|
||||
log.info(
|
||||
"Merged external IDs into manga '{}' (ID: {}): aniListId={}, malId={}",
|
||||
existing.getTitle(),
|
||||
existing.getId(),
|
||||
existing.getAniListId(),
|
||||
existing.getMalId());
|
||||
return mangaRepository.save(existing);
|
||||
}
|
||||
|
||||
return existing;
|
||||
}
|
||||
|
||||
private record ProviderResult(String title, Long externalId) {}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user