簡體   English   中英

從 gRPC StreamObserver “橋接” Reactor 的 Flux

[英]"Bridging" Reactor's Flux from gRPC StreamObserver

我想從gRPC StreamObserver創建一個Reactor Flux 只要 StreamObserver 本身沒有實現相應的接口,就需要這樣做(參見例如這個問題)。

我想出的大致如下:

final StreamObserver<ProtoResponse>[] streamObserverArray = new  StreamObserver[1];
Flux<Response> myFlux Flux.create(sink -> streamObserverArray[0] = new StreamObserver<ProtoResponse>() {
        @Override
        public void onNext(ProtoResponse value) {
            final Response response = convertFromProto(value);
            sink.next(response);
        }

        @Override
        public void onError(Throwable throwable) {
            sink.error(throwable);
        }

        @Override
        public void onCompleted() {
            sink.complete();
        }
    });
myFlux
    .doOnError(throwable -> {/* actual logic in here */}) //
    .doOnComplete(() -> {/* actual logic in here */}) //
    .doOnCancel(() -> {/* actual logic in here */}) //
    .parallel() //
    .runOn(Schedulers.parallel()) //
    .doOnNext(/* actual heavy lifting logic in here */) //
    .map(/* ... */) //
    .sequential() //
    .doOnNext(/* ...*/) //
    .subscribe(); // needed to start the actual processing of the events on this Flux

MyGrpcService.newStub(channel).getResponses(protoRequest, streamObserverArray[0]);

我在這里使用 Reactor 的主要想法是將“繁重的工作”並行分配到多個線程上,而不是在 gRPC 請求線程上執行此操作。

我看到該方法存在幾個問題,正如上面所做的那樣:

  • 我真的不喜歡StreamObserver[]數組的解決方法
  • 我需要先創建完整的流量,因為如果我不完成它.subscribe()第一, StreamObserver可能是null當GRPC開始通信(又名競態條件)。
  • 我不確定背壓是否按預期方式工作(盡管目前這不是我的主要關注點)。

所以我的問題是:從 gRPC StreamObserver 橋接到 Reactor Flux 的最佳/首選方式是什么? 有沒有最佳實踐?

現在有一個更簡單的解決方案:

https://github.com/salesforce/reactive-grpc

它支持將 gRPC 橋接到 Reactor 和 RxJava 2。

經過更多的擺弄和更好地理解整個反應性的東西之后,我想出了以下解決方案:

/**
* Bridge the StreamObserver from gRPC to the Publisher from the reactive world.
*/
public class StreamObserverPublisher implements Publisher<Long>, StreamObserver<Long> {

    private Subscriber<? super Long> subscriber;

    @Override
    public void onNext(Long l) {
        subscriber.onNext(l);
    }

    @Override
    public void onError(Throwable throwable) {
        subscriber.onError(throwable);
    }

    @Override
    public void onCompleted() {
        subscriber.onComplete();
    }

    @Override
    public void subscribe(Subscriber<? super Long> subscriber) {
        this.subscriber = subscriber;
        this.subscriber.onSubscribe(new BaseSubscriber() {});
    }
}

// and somewhere else in the code
StreamObserverPublisher streamObserverPublisher = new StreamObserverPublisher();
Flux<Long> longFlux = Flux.from(streamObserverPublisher);
longFlux.subscribe(...); // must be done before executing the gRPC request
MyGrpcService.newStub(channel).getResponses(protoRequest, streamObserverPublisher);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM