响应式流:Spring WebFlux - 订阅现有的发布者

4
我正在将我们现有的Spring异步REST架构迁移到Spring的新WebFlux库,关于如何连接多个请求以便它们可以监听相同发布的响应,我有一个问题。
以下是用例:
1.客户端A连接到我们的Web服务器并请求数据
2.我们检查缓存以查看是否有数据
3.我们没有,所以我们去检索这些数据(客户端A已经订阅并等待响应)
4.客户端B连接到我们的Web服务器并请求相同的数据(命中相同的端点)
5.我们检查缓存,数据仍不在那里
6.因为我们已经为客户端A获取了此数据,我们不想发出另一个请求,但我们也不想拒绝客户端B。客户端B应该能够监听相同的信息。
客户端B如何订阅与客户端A等待相同响应流的相同流?

你能提供代码片段展示缓存库API的样子吗?此外,这里期望的行为是什么?我认为缓存可能不包含要发送给客户端的原始响应,因此它是关于在服务层共享缓存数据,而不一定是在Web层。 - Brian Clozel
我只是想知道是否可以使用响应式模式实现。在示例中,缓存用于说明为什么请求可能无法立即获得响应。我想知道如果两个请求命中相同的端点,是否可以使用WebFlux将它们合并,并允许它们都等待同一个响应?显然,这不能通过经典的REST和Spring来完成,但我希望使用响应式流可以实现这种行为。 - wild_nothing
1个回答

8
“客户A已经订阅并等待响应”。 我认为请求被编码为Mono,客户A直接订阅它: Subscriber<Response> clientA = ... Mono<Response> request = makeRequest(...); request.subscribe(clientA); 然后客户B应该以同样的方式进行订阅: Subscriber<Response> clientB = ... request.subscribe(clientB); 此外,缓存应该包含的不是之前保存的响应数据,而是请求本身,类型为Mono<Response>。因此,如果在缓存中找到这样的请求,则新的客户端只需订阅它,无论该请求是否已完成。

1
在这个例子中,“缓存”只是一个非常轻量级的Hazelcast IMap数据结构。仅当外部数据不存在时,它才会被填充到其中。我的目标是以最优雅的方式强制执行外部数据调用(和缓存填充)不会发生两次。已经有多种方法可以解决这个问题,但我想知道是否可以通过WebFlux以简单的方式解决它——我的想法是两个请求监听相同的事件序列。我不能删除现有的IMap,但您认为我应该添加一个包含Mono<R>的新IMap吗? - wild_nothing
就像处理器有几个级别的缓存一样,您可以为当前请求添加另一级缓存,其中包含Mono<R>,而不必触及IMap。这可以是简单的HashMap。 - Alexei Kaigorodov
有趣的想法。谢谢。 - wild_nothing
1
你可以简单地将从缓存中接收到的响应移动到主缓存中: request.subscribe(response)->{ imapCache.put(response); responseCache.remove(request); } - Alexei Kaigorodov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接