Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java &引用;“桥接”;反应堆';来自gRPC StreamObserver的s通量_Java_Grpc_Project Reactor_Grpc Java - Fatal编程技术网

Java &引用;“桥接”;反应堆';来自gRPC StreamObserver的s通量

Java &引用;“桥接”;反应堆';来自gRPC StreamObserver的s通量,java,grpc,project-reactor,grpc-java,Java,Grpc,Project Reactor,Grpc Java,我想从创建一个。只要StreamObserver不以本机方式实现各自的接口,就需要这样做(例如,请参阅) 我的想法大致如下: final StreamObserver<ProtoResponse>[] streamObserverArray = new StreamObserver[1]; Flux<Response> myFlux Flux.create(sink -> streamObserverArray[0] = new StreamObserver<

我想从创建一个。只要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]);
final StreamObserver[]StreamObserver数组=新StreamObserver[1];
Flux myFlux Flux.create(sink->StreamObserver数组[0]=newstreamobserver(){
@凌驾
public void onNext(ProtoResponse值){
最终响应=convertFromProto(值);
下一步(响应);
}
@凌驾
公共作废登记员(可丢弃){
错误(可丢弃);
}
@凌驾
未完成的公共无效(){
sink.complete();
}
});
myFlux
.doOnError(可丢弃->{/*此处为实际逻辑*/})//
.doOnComplete(()->{/*此处为实际逻辑*/})//
.doOnCancel(()->{/*此处为实际逻辑*/})//
.parallel()//
.runOn(Schedulers.parallel())//
.doOnNext(/*此处为实际起重逻辑*/)//
.map(/*…*/)//
//
.doOnNext(/*…*/)//
.subscribe();//需要启动此流量上事件的实际处理
MyGrpcService.newStub(channel).getResponses(protoRequest,streamObserverArray[0]);
我想在这里使用Reactor的主要思想是将“繁重的工作”并行地分配到多个线程上,而不是在gRPC请求线程上这样做

如上所述,我发现该方法存在一些问题:

  • 我真的不喜欢使用
    StreamObserver[]
    数组的变通方法
  • 我需要首先创建完整的流量,因为如果我不首先使用
    .subscribe()
    完成它,当gRPC开始通信时,
    StreamObserver
    可能是
    null
    (也称竞争条件)
  • 我不确定背压是否按预期的方式工作(尽管这不是我目前主要关心的问题)
所以我的问题是:
将gRPC StreamObserver连接到反应堆通量的最佳/首选方式是什么?有什么最佳实践吗?

在做了更多的工作并更好地理解了整个反应性内容之后,我提出了以下解决方案:

/**
* 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);
/**
*将gRPC的StreamObserver连接到被动世界的发布者。
*/
公共类StreamObserverPublisher实现了发布服务器StreamObserver{

私人订户现在有一个更简单的解决方案:

/**
* 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);


它支持将gRPC连接到Reactor和RxJava 2。

感谢您将此放在这里。到目前为止,我们已在所有产品中使用该库,并对此感到满意!嗨,我只想知道为什么longFlux.subscribe()必须在执行gRPC请求之前进行。谢谢。@trjade:我真的不记得了,那差不多是三年前的事了,正如在另一个回答中提到的,我们已经用Salesforce提供的反应式gRPC库替换了我们的手动解决方案。