Compare commits

...

2 Commits

6 changed files with 39 additions and 1 deletions

View File

@ -125,6 +125,12 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId> <artifactId>spring-boot-starter-amqp</artifactId>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/io.github.resilience4j/resilience4j-spring-boot3 -->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot3</artifactId>
<version>2.3.0</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -2,12 +2,15 @@ package com.magamochi.mangamochi.client;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.util.List; import java.util.List;
import io.github.resilience4j.retry.annotation.Retry;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "jikan", url = "https://api.jikan.moe/v4/manga") @FeignClient(name = "jikan", url = "https://api.jikan.moe/v4/manga")
@Retry(name = "JikanRetry")
public interface JikanClient { public interface JikanClient {
@GetMapping @GetMapping
SearchResponse mangaSearch(@RequestParam String q); SearchResponse mangaSearch(@RequestParam String q);

View File

@ -3,10 +3,13 @@ package com.magamochi.mangamochi.client;
import com.magamochi.mangamochi.model.dto.MangaDexMangaDTO; import com.magamochi.mangamochi.model.dto.MangaDexMangaDTO;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import io.github.resilience4j.retry.annotation.Retry;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@FeignClient(name = "mangaDex", url = "https://api.mangadex.org") @FeignClient(name = "mangaDex", url = "https://api.mangadex.org")
@Retry(name = "MangaDexRetry")
public interface MangaDexClient { public interface MangaDexClient {
@GetMapping("/manga/{id}") @GetMapping("/manga/{id}")
MangaDexMangaDTO getManga(@PathVariable UUID id); MangaDexMangaDTO getManga(@PathVariable UUID id);

View File

@ -15,4 +15,9 @@ public class RateLimiterConfig {
public RateLimiter jikanRateLimiter() { public RateLimiter jikanRateLimiter() {
return RateLimiter.create(1); return RateLimiter.create(1);
} }
@Bean
public RateLimiter imageDownloadRateLimiter() {
return RateLimiter.create(10);
}
} }

View File

@ -1,5 +1,6 @@
package com.magamochi.mangamochi.service; package com.magamochi.mangamochi.service;
import com.google.common.util.concurrent.RateLimiter;
import com.magamochi.mangamochi.exception.UnprocessableException; import com.magamochi.mangamochi.exception.UnprocessableException;
import com.magamochi.mangamochi.model.dto.MangaChapterArchiveDTO; import com.magamochi.mangamochi.model.dto.MangaChapterArchiveDTO;
import com.magamochi.mangamochi.model.dto.MangaChapterImagesDTO; import com.magamochi.mangamochi.model.dto.MangaChapterImagesDTO;
@ -36,6 +37,8 @@ public class MangaChapterService {
private final ContentProviderFactory contentProviderFactory; private final ContentProviderFactory contentProviderFactory;
private final RateLimiter imageDownloadRateLimiter;
@Transactional @Transactional
public void fetchChapter(Long chapterId) { public void fetchChapter(Long chapterId) {
var chapter = getMangaChapterThrowIfNotFound(chapterId); var chapter = getMangaChapterThrowIfNotFound(chapterId);
@ -50,9 +53,11 @@ public class MangaChapterService {
} }
var chapterImages = var chapterImages =
chapterImagesUrls.entrySet().stream() chapterImagesUrls.entrySet().parallelStream()
.map( .map(
entry -> { entry -> {
imageDownloadRateLimiter.acquire();
try { try {
var inputStream = var inputStream =
new BufferedInputStream( new BufferedInputStream(

View File

@ -51,3 +51,19 @@ jwt:
manga-matcher: manga-matcher:
endpoint: ${MANGAMATCHER_ENDPOINT} endpoint: ${MANGAMATCHER_ENDPOINT}
resilience4j:
retry:
instances:
MangaDexRetry:
max-attempts: 5
wait-duration:
seconds: 5
retry-exceptions:
- feign.FeignException
JikanRetry:
max-attempts: 5
wait-duration:
seconds: 5
retry-exceptions:
- feign.FeignException