PublishOn Reactor异步磁通和线程锁定

时间:2018-10-09 22:20:44

标签: java project-reactor

我正在尝试建立遵循以下步骤的方案:

  1. (在Init上创建了Flux发布者
  2. (在Init上)订户subscribe
  3. (根据用户操作)发布者开始流式传输/发布事件
  4. Web控制器订阅者使用并缓存最近的BUFFER_SIZE个事件

基于http://projectreactor.io/docs/core/release/reference/#advanced-parallelizing-parralelfluxhttps://www.baeldung.com/reactor-core,我正在尝试使用createpublish来执行此操作,而我遇到的问题是调用的线程flux.connect被困在发布者内部的while循环中。

以下是使用spring-boot-starter-webflux的最小工作示例:

private ConnectableFlux<Integer> flux;
private Scheduler scheduler;
private int nextRead = 0;

private static final int BUFFERSIZE = 100;
private List<Integer> sink = new LinkedList<Integer>() ;

@PostConstruct
public void Init() {
    this.scheduler = Schedulers.newSingle("Streamer");

    flux = Flux.<Integer>create(fluxSink -> {
        while (true) {
            fluxSink.next(nextRead++);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }).publishOn(scheduler).publish();
}

@GetMapping("/subscribe")
public void subscribe(){
    this.flux.subscribeOn(scheduler,false).subscribe(new CoreSubscriber<Integer>() {
        @Override
        public Context currentContext() {
            return null;
        }

        @Override
        public void onSubscribe(Subscription subscription) {
            subscription.request(Long.MAX_VALUE);
        }

        @Override
        public void onNext(Integer e) {
            while (sink.size() >= BUFFERSIZE) sink.remove(0);
            sink.add(e);
            logger.debug("sink event: " + e);
        }

        @Override
        public void onError(Throwable t) {}

        @Override
        public void onComplete() {}
    });
}

@GetMapping("/start")
public void startStream(){
    logger.debug("EventStreamSimulator startStream before connect");
    this.flux.connect();
    logger.debug("EventStreamSimulator startStream after connect");
}

@GetMapping("/values")
public Flux<Integer> getEvents(){
    return Flux.fromIterable(sink);
}

基于此代码,/start上的Web请求将开始流式传输,但是http线程将陷入发射器无限循环中。 /values上的请求和日志记录表明它运行正常(但是原来的http request/start从未完成/返回)

示例日志:

  

2018-10-09 18:12:54.798调试6024 --- [ctor-http-nio-2] com.example.FluxPocController:emmit事件:0

     

2018-10-09 18:12:54.798调试6024 --- [Streamer-1] com.example.FluxPocController:下沉事件:0

然后,这是一个问题:使用publishOn的这些异步方式是否支持Flux.create指令?如果可以,怎么使用?

0 个答案:

没有答案