在递归调用中收集 CompletableFuture 结果
Collect CompletableFuture results in recursive calls
我有以下代码,即从 Web API 获取给定时间间隔的报告 returns CompletableFuture。如果超过 returned 报告的行数,时间间隔将被分成两半,并且 API 将被调用。这将递归重复,直到行数满足条件。
我想得到 CompletableFuture>
或者更好的 List> 作为此方法的结果。
我的代码运行在不需要区间分割的情况下可以。如果需要递归调用,它将 return 只是空列表,稍后异步执行递归调用。
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;
});
}
我也试过用类似的东西,但没有用:
response
.thenAccept(r -> generateDomainReport(domain, chunkStartDate, chunkMiddleDate, result))
.thenAccept(r -> generateDomainReport(domain, chunkMiddleDate, chunkEndDate, result));
如果知道我做错了什么,我将不胜感激。谢谢
我将我的原始代码转换为类似这样的代码,它似乎可以正常工作:
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);
}
});
}
我有以下代码,即从 Web API 获取给定时间间隔的报告 returns CompletableFuture。如果超过 returned 报告的行数,时间间隔将被分成两半,并且 API 将被调用。这将递归重复,直到行数满足条件。
我想得到 CompletableFuture>
或者更好的 List
我的代码运行在不需要区间分割的情况下可以。如果需要递归调用,它将 return 只是空列表,稍后异步执行递归调用。
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;
});
}
我也试过用类似的东西,但没有用:
response
.thenAccept(r -> generateDomainReport(domain, chunkStartDate, chunkMiddleDate, result))
.thenAccept(r -> generateDomainReport(domain, chunkMiddleDate, chunkEndDate, result));
如果知道我做错了什么,我将不胜感激。谢谢
我将我的原始代码转换为类似这样的代码,它似乎可以正常工作:
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);
}
});
}