我的用例是创建一个像这样的反应性端点:
public Flux<ServerEvent> getEventFlux(Long forId){
ServicePoller poller = new ServicePollerImpl();
Map<String,Object> params = new HashMap<>();
params.put("id", forId);
Flux<Long> interval = Flux.interval(Duration.ofMillis(pollDuration));
Flux<ServerEvent> serverEventFlux =
Flux.fromStream(
poller.getEventStream(url, params) //poll a given endpoint after a fixed duration.
);
Flux<ServerEvent> sourceFlux= Flux.zip(interval, serverEventFlux)
.map(Tuple2::getT2); // Zip the two streams.
/* Here I want to store data from sourceFlux into a collection whenever some data arrives without disturbing the downstream processing in Spring. So that I can access collection later on without polling again */
这会在数据可用时立即将其发送回前端,但是我的第二个用例是在数据到达一个单独的集合时将其合并,以便如果以后有类似的请求到达,我可以卸载来自池的整个数据而无需再次点击服务。
我试图在从原始流量控制器返回之前,先预订磁通量,缓冲区,缓存并收集流量,但所有这些似乎都关闭了流,因此Spring无法对其进行处理。
在不关闭助焊剂流的情况下,什么时候可以使用助焊剂并将值存储到集合中?
遇到异常:
java.lang.IllegalStateException:流已被操作 或在关闭 java.util.stream.AbstractPipeline.spliterator(AbstractPipeline.java:343) 〜[na:1.8.0_171]在 java.util.stream.ReferencePipeline.iterator(ReferencePipeline.java:139) 〜[na:1.8.0_171]在 Reactor.core.publisher.FluxStream.subscribe(FluxStream.java:57) 〜[reactor-core-3.1.7.RELEASE.jar:3.1.7.RELEASE]在 Reactor.core.publisher.Flux.subscribe(Flux.java:6873) 〜[reactor-core-3.1.7.RELEASE.jar:3.1.7.RELEASE]在 Reactor.core.publisher.FluxZip $ ZipCoordinator.subscribe(FluxZip.java:573) 〜[reactor-core-3.1.7.RELEASE.jar:3.1.7.RELEASE]在 Reactor.core.publisher.FluxZip.handleBoth(FluxZip.java:326) 〜[reactor-core-3.1.7.RELEASE.jar:3.1.7.RELEASE]
答案 0 :(得分:1)
poller.getEventStream
返回一个Java 8流,该流只能使用一次。您可以先将流转换为集合,也可以使用供应商来推迟执行poller.getEventStream
:
Flux.fromStream(
() -> poller.getEventStream(url, params)
);
答案 1 :(得分:0)
一个更好的Oliver建议的对我有用的解决方案
public Flux<ServerEvent> getEventFlux(Long forId){
ServicePoller poller = new ServicePollerImpl();
Map<String,Object> params = new HashMap<>();
params.put("id", forId);
Flux<Long> interval = Flux.interval(Duration.ofMillis(pollDuration));
Flux<ServerEvent> serverEventFlux =
Flux.fromStream(
()->{
return poller.getEventStream(url, params).peek((se)->{reactSink.addtoSink(forId, se);});
}
);
Flux<ServerEvent> sourceFlux= Flux.zip(interval, serverEventFlux)
.map(Tuple2::getT2);
return sourceFlux;
}