Compare commits
2 Commits
c0d4e4084a
...
6b2a77b391
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b2a77b391 | |||
| 948dd7fb9e |
6
pom.xml
6
pom.xml
@ -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>
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user