I have following code, that is getting reports for given time interval from web API that returns CompletableFuture. In case that count of rows for returned report was exceeded, time interval will be splited into 2 half and API will be called for both halfs. This will be recursively repeated until count of rows satisfy condition.
I would like to get CompletableFuture<List<APIResult>> or even better List<CompletableFuture<APIResult>> as result of this method.
My code run ok when there is no need for interval splitting. In case when recursion call is needed it will return just empty list and recursive calls are executed later on asynchronously.
protected CompletableFuture<List<APIResult<String>>> generateDomainReport(
ExtendedDomainConfiguration domain,
ZonedDateTime chunkStartDate,
ZonedDateTime chunkEndDate,
List<APIResult<String>> result) {
CompletableFuture<APIResult<String>> response = runReport(domain.getDomainName(), chunkStartDate, chunkEndDate);
return response.thenApply(report -> {
// in case that count of report rows hit the limit, split timeWindow into two half,
// calculate middle date and run report for both intervals: <startDate, middleDate>; <middleDate, endDate>
if (isReportMaxRowCountReached(report.getContent(), domain.getMaxReportRowCount())) {
LOGGER.warn(String.format(
"Report limit row counts was reached. "
"Splitting window <%s, %s> into 2 parts and rerunning report",
chunkStartDate, chunkEndDate));
Duration timeWindow = Duration.between(chunkStartDate, chunkEndDate);
ZonedDateTime chunkMiddleDate = chunkEndDate.minus(Duration.ofSeconds(timeWindow.getSeconds() / 2));
// recursively repeat until count of returned rows is under the limit
generateDomainReport(domain, chunkStartDate, chunkMiddleDate, result);
generateDomainReport(domain, chunkMiddleDate, chunkEndDate, result);
} else {
result.add(report);
}
return result;
});
}
I also tried use something like that but it didn't helped:
response
.thenAccept(r -> generateDomainReport(domain, chunkStartDate, chunkMiddleDate, result))
.thenAccept(r -> generateDomainReport(domain, chunkMiddleDate, chunkEndDate, result));
I will be thankful for any idea what I am doing wrong. Thanks
CodePudding user response:
I transformed my original code to something like this and it seems to be working:
protected CompletableFuture<List<APIResult<String>>> generateDomainReport(
ExtendedDomainConfiguration domain,
ZonedDateTime chunkStartDate,
ZonedDateTime chunkEndDate) {
CompletableFuture<APIResult<String>> response = runReport(domain.getDomainName(), chunkStartDate, chunkEndDate);
return response.thenApplyAsync(report -> {
// in case that count of report rows hit the limit, split timeWindow into two half,
// calculate middle date and run report for both intervals: <startDate, middleDate>; <middleDate, endDate>
if (isReportMaxRowCountReached(report.getContent(), domain.getMaxReportRowCount())) {
LOGGER.warn(String.format(
"CSV report limit row counts was reached. "
"Splitting window <%s, %s> into 2 parts and rerunning report",
chunkStartDate, chunkEndDate));
Duration timeWindow = Duration.between(chunkStartDate, chunkEndDate);
ZonedDateTime chunkMiddleDate = chunkEndDate.minus(Duration.ofSeconds(timeWindow.getSeconds() / 2));
// recursively repeat until count of returned rows is under the limit
return generateDomainReport(domain, chunkStartDate, chunkMiddleDate)
.thenCombineAsync(generateDomainReport(domain, chunkMiddleDate, chunkEndDate),
(result1, result2) -> {
List<APIResult<String>> result = new ArrayList<>(result1.size() result2.size());
result.addAll(result1);
result.addAll(result2);
return result;
}).join();
} else {
return List.of(report);
}
});
}