我有一个微服务,该服务使用ReactiveMongoRepository
接口从数据库读取对象。
目标是获取这些对象中的每个对象并将其推送到AWS Lambda函数(将其转换为DTO之后)。如果该lambda函数的结果在200范围内,则将该对象标记为成功,否则将其忽略。
在过去的简单Mongo存储库和RestTemplate中,这是一件微不足道的任务。但是,我试图理解此无功交易,并避免阻塞。
这是我想出的代码,我知道我在webClient
上受阻,但是如何避免呢?
@Override
public Flux<Video> index() {
return videoRepository.findAllByIndexedIsFalse().flatMap(video -> {
final SearchDTO searchDTO = SearchDTO.builder()
.name(video.getName())
.canonicalPath(video.getCanonicalPath())
.objectID(video.getObjectID())
.userId(video.getUserId())
.build();
// Blocking call
final HttpStatus httpStatus = webClient.post()
.uri(URI.create(LAMBDA_ENDPOINT))
.body(BodyInserters.fromObject(searchDTO)).exchange()
.block()
.statusCode();
if (httpStatus.is2xxSuccessful()) {
video.setIndexed(true);
}
return videoRepository.save(video);
});
}
我是从计划任务中调用上述代码的,而我实际上并不关心index()方法的实际结果,而只是在执行期间会发生什么。
@Scheduled(fixedDelay = 60000)
public void indexTask() {
indexService
.index()
.log()
.subscribe();
}
我已经阅读了很多有关该主题的博客文章,但它们只是简单的CRUD操作,中间没有发生任何事情,因此请不要真正给我提供有关如何实现这些内容的完整信息。
有帮助吗?
答案 0 :(得分:1)
您的解决方案实际上非常接近。 在这种情况下,您应该逐步分解反应链,而为了清晰起见,请毫不犹豫地将位转换为独立的方法。
@Override
public Flux<Video> index() {
Flux<Video> unindexedVideos = videoRepository.findAllByIndexedIsFalse();
return unindexedVideos.flatMap(video -> {
final SearchDTO searchDTO = SearchDTO.builder()
.name(video.getName())
.canonicalPath(video.getCanonicalPath())
.objectID(video.getObjectID())
.userId(video.getUserId())
.build();
Mono<ClientResponse> indexedResponse = webClient.post()
.uri(URI.create(LAMBDA_ENDPOINT))
.body(BodyInserters.fromObject(searchDTO)).exchange()
.filter(res -> res.statusCode().is2xxSuccessful());
return indexedResponse.flatMap(response -> {
video.setIndexed(true);
return videoRepository.save(video);
});
});
答案 1 :(得分:0)
我的方法,可能更具可读性。但是我承认我没有运行它,所以不能100%保证它会运行。
public Flux<Video> index() {
return videoRepository.findAll()
.flatMap(this::callLambda)
.flatMap(videoRepository::save);
}
private Mono<Video> callLambda(final Video video) {
SearchDTO searchDTO = new SearchDTO(video);
return webClient.post()
.uri(URI.create(LAMBDA_ENDPOINT))
.body(BodyInserters.fromObject(searchDTO))
.exchange()
.map(ClientResponse::statusCode)
.filter(HttpStatus::is2xxSuccessful)
.map(t -> {
video.setIndexed(true);
return video;
});
}