Skip to content

Commit e659c60

Browse files
committed
http 429 in jsonresttask
1 parent bc19de5 commit e659c60

File tree

3 files changed

+65
-18
lines changed

3 files changed

+65
-18
lines changed

src/main/java/de/mediathekview/mserver/crawler/arte/tasks/ArteVideoInfoTask.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ protected void postProcessingNextPage(PagedElementListDTO<ArteVideoInfoDto> aRes
6464

6565
protected void postProcessingElements(Set<ArteVideoInfoDto> elements, TopicUrlDTO aDTO) {
6666
for (ArteVideoInfoDto element : elements) {
67-
taskResults.add(element);
67+
if(!taskResults.add(element)) {
68+
log.debug("Duplicate film");
69+
}
6870
}
6971
}
7072

src/main/java/de/mediathekview/mserver/crawler/arte/tasks/ArteVideoLinkTask.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import de.mediathekview.mserver.crawler.basic.AbstractCrawler;
1919
import de.mediathekview.mserver.crawler.basic.AbstractJsonRestTask;
2020
import de.mediathekview.mserver.crawler.basic.AbstractRecursiveConverterTask;
21-
import de.mediathekview.mserver.crawler.basic.PagedElementListDTO;
2221
import jakarta.ws.rs.core.Response;
2322

2423
//return T Class from this task, desirialisation of class R , D , Reasearch in this url

src/main/java/de/mediathekview/mserver/crawler/basic/AbstractJsonRestTask.java

Lines changed: 62 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,16 @@
1313
import java.util.Optional;
1414
import java.util.Queue;
1515

16+
import org.apache.logging.log4j.LogManager;
17+
import org.apache.logging.log4j.Logger;
18+
1619
import static jakarta.ws.rs.core.HttpHeaders.ACCEPT_CHARSET;
1720
import static jakarta.ws.rs.core.HttpHeaders.ACCEPT_ENCODING;
1821

1922
/** A abstract REST api task which requests the given url with the Funk Api settings. */
2023
public abstract class AbstractJsonRestTask<T, R, D extends CrawlerUrlDTO>
2124
extends AbstractRestTask<T, D> {
25+
protected final transient Logger log = LogManager.getLogger(this.getClass());
2226
protected static final String ENCODING_GZIP = "gzip";
2327
private static final long serialVersionUID = -1090560363478964885L;
2428
protected final transient GsonBuilder gsonBuilder;
@@ -41,24 +45,66 @@ protected AbstractJsonRestTask(
4145

4246
@Override
4347
protected void processRestTarget(final D aDTO, final WebTarget aTarget) {
44-
gsonBuilder.registerTypeAdapter(getType(), getParser(aDTO));
45-
final Gson gson = gsonBuilder.create();
46-
Builder request = aTarget.request();
47-
final Optional<String> authKey = getAuthKey();
48-
if (authKey.isPresent()) {
49-
request = request.header(HEADER_AUTHORIZATION, authKey.get());
50-
}
48+
gsonBuilder.registerTypeAdapter(getType(), getParser(aDTO));
49+
final Gson gson = gsonBuilder.create();
5150

52-
final Response response = createResponse(request, aDTO);
53-
54-
if (response.getStatus() == 200) {
55-
final String jsonOutput = response.readEntity(String.class);
56-
final R responseObj = gson.fromJson(jsonOutput, getType());
57-
postProcessing(responseObj, aDTO);
58-
} else {
59-
handleHttpError(aDTO, aTarget.getUri(), response);
60-
}
51+
Builder request = aTarget.request();
52+
final Optional<String> authKey = getAuthKey();
53+
if (authKey.isPresent()) {
54+
request = request.header(HEADER_AUTHORIZATION, authKey.get());
55+
}
56+
final int maxRetries = 3;
57+
int attempt = 0;
58+
while (attempt < maxRetries) {
59+
attempt++;
60+
Response response = null;
61+
try {
62+
response = createResponse(request, aDTO);
63+
int status = response.getStatus();
64+
if (status == 200) {
65+
final String jsonOutput = response.readEntity(String.class);
66+
final R responseObj = gson.fromJson(jsonOutput, getType());
67+
postProcessing(responseObj, aDTO);
68+
return;
69+
}
70+
if (status == 429 && attempt < maxRetries) {
71+
final long proposalWaitMillis = getRetryAfterMillis(response).orElse(1000L) * attempt;
72+
long waitMillis = proposalWaitMillis;
73+
if (waitMillis < 100) {
74+
waitMillis = 100;
75+
} else if (waitMillis > 180000 ) {
76+
waitMillis = 180000;
77+
}
78+
//log.debug("Too Many Requests - propsoal: {} waiting: {} ", proposalWaitMillis, waitMillis);
79+
Thread.sleep(waitMillis);
80+
continue;
81+
}
82+
handleHttpError(aDTO, aTarget.getUri(), response);
83+
return;
84+
} catch (InterruptedException e) {
85+
Thread.currentThread().interrupt();
86+
throw new RuntimeException("Retry interrupted", e);
87+
} finally {
88+
if (response != null) {
89+
response.close();
90+
}
91+
}
92+
}
6193
}
94+
95+
private Optional<Long> getRetryAfterMillis(Response response) {
96+
String retryAfter = response.getHeaderString("Retry-After");
97+
if (retryAfter == null) {
98+
return Optional.empty();
99+
}
100+
try {
101+
long seconds = Long.parseLong(retryAfter);
102+
return Optional.of(seconds * 1000);
103+
} catch (NumberFormatException e) {
104+
return Optional.empty();
105+
}
106+
}
107+
62108

63109
protected Response createResponse(final Builder request, final D aDTO) {
64110
request.header(ACCEPT_CHARSET, StandardCharsets.UTF_8);

0 commit comments

Comments
 (0)