[英]"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 的最佳/首選方式是什么? 有沒有最佳實踐?
經過更多的擺弄和更好地理解整個反應性的東西之后,我想出了以下解決方案:
/**
* 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.