我遇到了 WSClient 的某种阻塞或竞争情况。我有一个函数可以从返回 CompletationStage 的外部 API REST 获取数据:
public CompletionStage<BCApiResponse> getWorker(String workerID) {
Logger.info("STARTED: " + workerID);
// ws is the injected WSClient instance
return ws.url(host + "/getWorker/" + workerID)
.setContentType("application/json")
.get()
.thenApply(r -> {
Logger.info("COMPLETED: " + workerID);
if (r.getStatus() == Http.Status.OK) {
try {
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = Json.toJson(new ObjectMapper().readTree(r.getBody()));
return objectMapper.readValue(jsonNode.toString(), BCApiResponse.class);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
} else {
Logger.error(host + "/getWorker: " + r.getBody());
return null;
}
});
}
我需要为列表的每个元素(WorkerExperience)调用此函数并更新其中一个字段:
List<CompletableFuture<WorkExperienceView>> completableFutures =
st.map(exp -> addVerifications(exp))
.collect(Collectors.toList());
CompletableFuture<Void> allFutures = CompletableFuture
.allOf(completableFutures
.toArray(new CompletableFuture[completableFutures.size()]));
CompletableFuture<List<WorkExperienceView>> allCompletableFuture = allFutures.thenApply(future -> completableFutures.stream()
.map(completableFuture -> completableFuture.join())
.collect(Collectors.toList()));
List<WorkExperienceView> experiences;
experiences = allCompletableFuture.get();
...
(来自:Fantastic CompletableFuture.allOf() 以及如何处理错误。)
这是 addVerification 的代码
private CompletableFuture<WorkExperienceView> addVerifications(WorkExperienceView exp) {
return (bcAPI.getWorker(exp.getId().toString())
.thenApply(response -> {
// Test code
exp.setVerifications(111L);
return exp;
})).toCompletableFuture();
}
我在控制台中收到此日志消息:
[info] application - STARTED: 20
[info] application - STARTED: 21
[info] application - STARTED: 22
[info] application - STARTED: 18
[info] application - STARTED: 19
[info] application - COMPLETED: 19
和代码卡在
experiences = allCompletableFuture.get();
知道有什么问题吗?我怎样才能解决这个问题?
谢谢!