[英]Webflux subscriber
I'm currently facing an issue about saving on redis inside a switchIfEmpty function.我目前面临一个关于在 switchIfEmpty function 中保存 redis 的问题。 Probably is related to the fact I'm pretty new in Reactive Programming and unfortunately I struggling to find proper examples about it.
可能与我在反应式编程中相当新的事实有关,不幸的是我很难找到有关它的适当示例。
However I've been able to solve it but I'm pretty sure there's a better way to do it.但是我已经能够解决它,但我很确定有更好的方法来解决它。 Here is what I wrote now:
这是我现在写的:
public Mono<ResponseEntity<BaseResponse<Content>>> getContent(final String contentId, final String contentType){
return redisRepository.findByKeyAndId(REDIS_KEY_CONTENT, contentId.toString()).cast(Content.class)
.map(contentDTO -> ResponseEntity.status(HttpStatus.OK.value())
.body(new BaseResponse<>(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), contentDTO)))
//here I have to defer, otherwise It would never wait for the findByKeyAndId
.switchIfEmpty(Mono.defer(() -> {
Mono<ResponseEntity<BaseResponse<Content>>> responseMono = contentService.getContentByIdAndType(contentId, contentType);
//so far I understood I need to consume every stream I have, in order to actually carry out the task otherwise will be there waiting for a consumer.
//once I get what I need from the cmsService I need to put it in cache and till now this is the only way I've been able to do it
responseMono.filter(response -> response.getStatusCodeValue() == HttpStatus.OK.value())
.flatMap(contentResponse -> redisRepository.save(REDIS_KEY_CONTENT, contentId.toString(), contentResponse.getBody().getData()))
.subscribe();
//then I return the Object I firstly retrived thru the cmsService
return responseMono;
}
));
}
any clue or suggestion of better ways to do it?有什么更好的方法的线索或建议吗? Thank you in advance for the help!
预先感谢您的帮助!
There's a few things that aren't great from a best practice perspective there, and this probably isn't doing exactly what you think it's doing:从最佳实践的角度来看,有一些事情不是很好,这可能并没有完全按照你的想法做:
Mono.defer()
- usually, nothing would happen until the framework subscribed to your publisher at the correct time, whereas you're managing the subscription lifecycle for that publisher yourself.Mono.defer()
的原因 - 通常,在框架在正确的时间订阅您的发布者之前什么都不会发生,而您自己管理该发布者的订阅生命周期。Mono
that you're returning doesn't do anything with its result.Mono
对其结果没有任何作用。 So you'll likely be calling contentService.getContentByIdAndType()
twice, not just once - once when you subscribe, and once when the framework subscribes.contentService.getContentByIdAndType()
两次,而不仅仅是一次 - 一次是在您订阅时,一次是在框架订阅时。contentId
is already a string, you don't need to call toString()
on it:-)contentId
已经是一个字符串,你不需要在它上面调用toString()
:-) Instead, you might consider making use of delayUntil
inside your switchIfEmpty()
block - this will allow you to save the value to redis if the response code is ok, delay until this has happened, and keep the original value when done.相反,您可能会考虑在您的
switchIfEmpty()
块中使用delayUntil
- 如果响应代码正常,这将允许您将值保存到 redis,延迟直到发生这种情况,并在完成后保留原始值。 The code might look something like this (difficult to say if this is exactly correct without a complete example, but it should give you the idea):代码可能看起来像这样(如果没有完整的示例,很难说这是否完全正确,但它应该给你一个想法):
return redisRepository
.findByKeyAndId(REDIS_KEY_CONTENT, contentId).cast(Content.class)
.map(contentDTO -> ResponseEntity.status(HttpStatus.OK.value()).body(new BaseResponse<>(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), contentDTO)))
.switchIfEmpty(
contentService.getContentByIdAndType(contentId, contentType)
.delayUntil(response -> response.getStatusCodeValue() == HttpStatus.OK.value() ?
redisRepository.save(REDIS_KEY_CONTENT, contentId, contentResponse.getBody().getData()) :
Mono.empty())
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.