Java Reactor单执行并行任务

Java Reactor单执行并行任务,java,reactive-programming,spring-webflux,project-reactor,reactor,Java,Reactive Programming,Spring Webflux,Project Reactor,Reactor,我不熟悉Reactor框架,并尝试在现有的实现中使用它。LocationProfileService和InventoryService都返回一个Mono,并并行执行,彼此之间没有依赖关系(来自MainService)。在LocationProfileService中-发出了4个查询,最后2个查询依赖于第一个查询 写这篇文章的更好方法是什么?我看到调用按顺序执行,而其中一些调用应该并行执行。正确的方法是什么 public class LocationProfileService {

我不熟悉Reactor框架,并尝试在现有的实现中使用它。LocationProfileService和InventoryService都返回一个Mono,并并行执行,彼此之间没有依赖关系(来自MainService)。在LocationProfileService中-发出了4个查询,最后2个查询依赖于第一个查询

写这篇文章的更好方法是什么?我看到调用按顺序执行,而其中一些调用应该并行执行。正确的方法是什么

public class LocationProfileService {
        static final Cache<String, String> customerIdCache //define Cache

        @Override
        public Mono<LocationProfileInfo> getProfileInfoByLocationAndCustomer(String customerId, String location) {
            //These 2 are not interdependent and can be executed immediately
            Mono<String> customerAccountMono = getCustomerArNumber(customerId,location) LocationNumber).subscribeOn(Schedulers.parallel()).switchIfEmpty(Mono.error(new CustomerNotFoundException(location, customerId))).log();
            Mono<LocationProfile> locationProfileMono = Mono.fromFuture(//location query).subscribeOn(Schedulers.parallel()).log();

    //Should block be called, or is there a better way to do ?
            String custAccount = customerAccountMono.block(); // This is needed to execute and the value from this is needed for the next 2 calls

            Mono<Customer> customerMono = Mono.fromFuture(//query uses custAccount from earlier step).subscribeOn(Schedulers.parallel()).log();
            Mono<Result<LocationPricing>> locationPricingMono = Mono.fromFuture(//query uses custAccount from earlier step).subscribeOn(Schedulers.parallel()).log();

            return Mono.zip(locationProfileMono,customerMono,locationPricingMono).flatMap(tuple -> {
                LocationProfileInfo locationProfileInfo = new LocationProfileInfo();
                //populate values from tuple
                return Mono.just(locationProfileInfo);
            });


        }

        private Mono<String> getCustomerAccount(String conversationId, String customerId, String location) {
            return CacheMono.lookup((Map)customerIdCache.asMap(),customerId).onCacheMissResume(Mono.fromFuture(//query).subscribeOn(Schedulers.parallel()).map(x -> x.getAccountNumber()));
        }

}


public class InventoryService {

    @Override
    public Mono<InventoryInfo> getInventoryInfo(String inventoryId) {
        Mono<Inventory> inventoryMono = Mono.fromFuture(//inventory query).subscribeOn(Schedulers.parallel()).log();
        Mono<List<InventorySale>> isMono = Mono.fromFuture(//inventory sale query).subscribeOn(Schedulers.parallel()).log();

        return Mono.zip(inventoryMono,isMono).flatMap(tuple -> {
            InventoryInfo inventoryInfo = new InventoryInfo();
            //populate value from tuple

            return Mono.just(inventoryInfo);

        });
    }

}

public class MainService {

        @Autowired
        LocationProfileService locationProfileService;
        @Autowired
        InventoryService inventoryService

        public void mainService(String customerId, String location, String inventoryId) {
            Mono<LocationProfileInfo> locationProfileMono = locationProfileService.getProfileInfoByLocationAndCustomer(....);
            Mono<InventoryInfo> inventoryMono = inventoryService.getInventoryInfo(....);

            //is using block fine or is there a better way to do?
            Mono.zip(locationProfileMono,inventoryMono).subscribeOn(Schedulers.parallel()).block();
        }

}
公共类LocationProfileService{
静态最终缓存customerIdCache//定义缓存
@凌驾
公共Mono getProfileInfoByLocationAndCustomer(字符串customerId,字符串位置){
//这两项不是相互依赖的,可以立即执行
Mono customerAccountMono=getCustomerArNumber(customerId,location)LocationNumber).subscribeOn(Schedulers.parallel()).switchIfEmpty(Mono.error(new CustomerNotFoundException(location,customerId)).log();
Mono locationProfileMono=Mono.fromFuture(//位置查询).subscribeOn(Schedulers.parallel()).log();
//应该调用block,还是有更好的方法?
String custAccount=customerAccountMono.block();//执行时需要使用该值,接下来的2次调用需要使用该值中的值
Mono customerMono=Mono.fromFuture(//查询使用前面步骤中的custAccount);
Mono locationPricingMono=Mono.fromFuture(//查询使用前面步骤中的custAccount);
返回Mono.zip(locationProfileMono、customerMono、locationPricingMono).flatMap(元组->{
LocationProfileInfo LocationProfileInfo=新的LocationProfileInfo();
//从元组填充值
返回Mono.just(locationProfileInfo);
});
}
私有Mono getCustomerAccount(字符串会话ID、字符串customerId、字符串位置){
返回CacheMono.lookup((Map)customerIdCache.asMap(),customerId).onCacheMissResume(Mono.fromFuture(//query).subscribeOn(Schedulers.parallel()).Map(x->x.getAccountNumber());
}
}
公共类目录服务{
@凌驾
public Mono getInventoryInfo(字符串inventoryId){
Mono inventoryMono=Mono.fromFuture(//库存查询).subscribeOn(Schedulers.parallel()).log();
Mono isMono=Mono.fromFuture(//库存销售查询).subscribeOn(Schedulers.parallel()).log();
返回Mono.zip(inventoryMono,isMono).flatMap(元组->{
InventoryInfo InventoryInfo=新的InventoryInfo();
//从元组填充值
返回Mono.just(inventoryInfo);
});
}
}
公共类主服务{
@自动连线
LocationProfileService LocationProfileService;
@自动连线
库存服务库存服务
公共void mainService(字符串customerId、字符串位置、字符串inventoryId){
Mono locationProfileMono=locationProfileService.getProfileInfoByLocationAndCustomer(..);
Mono inventoryMono=inventoryService.getInventoryInfo(..);
//使用block是好的还是有更好的方法?
zip(locationProfileMono,inventoryMono).subscribeOn(Schedulers.parallel()).block();
}
}

您无需阻塞即可获得pass参数,因为您的代码非常接近解决方案。我使用您提供的类名编写了代码。只需将所有Mono.Just(..)替换为对正确服务的调用

    public Mono<LocationProfileInfo> getProfileInfoByLocationAndCustomer(String customerId, String location) {
    Mono<String> customerAccountMono = Mono.just("customerAccount");
    Mono<LocationProfile> locationProfileMono = Mono.just(new LocationProfile());

    return Mono.zip(customerAccountMono, locationProfileMono)
            .flatMap(tuple -> {
                Mono<Customer> customerMono = Mono.just(new Customer(tuple.getT1()));
                Mono<Result<LocationPricing>> result = Mono.just(new Result<LocationPricing>());
                Mono<LocationProfile> locationProfile = Mono.just(tuple.getT2());
                return Mono.zip(customerMono, result, locationProfile);
            })
            .map(LocationProfileInfo::new)
    ;
}

public static class LocationProfileInfo {
    public LocationProfileInfo(Tuple3<Customer, Result<LocationPricing>, LocationProfile> tuple){
        //do wathever
    }
}


public static class LocationProfile {}

private static class Customer {
    public Customer(String cutomerAccount) {
    }
}

private static class Result<T> {}

private static class LocationPricing {}
公共Mono getProfileInfoByLocationAndCustomer(字符串customerId,字符串位置){ Mono customerAccountMono=Mono.just(“customerAccount”); Mono locationProfileMono=Mono.just(new LocationProfile()); return Mono.zip(customerAccountMono,locationProfileMono) .flatMap(元组->{ Mono customerMono=Mono.just(新客户(tuple.getT1()); Mono result=Mono.just(new result()); Mono locationProfile=Mono.just(tuple.getT2()); 返回Mono.zip(customerMono、result、locationProfile); }) .map(LocationProfileInfo::新建) ; } 公共静态类LocationProfileInfo{ 公共位置配置文件信息(Tuple3 tuple){ //杜瓦瑟弗 } } 公共静态类LocationProfile{} 私有静态类客户{ 公共客户(字符串客户帐户){ } } 私有静态类结果{} 私有静态类LocationPricing{} 请记住,第一个拉链不是必需的。我重写它是为了得到你的解决方案。但我会用不同的方式来解决这个问题。这会更清楚

public Mono<LocationProfileInfo> getProfileInfoByLocationAndCustomer(String customerId, String location) {
return Mono.just("customerAccount") //call the service                                                
        .flatMap(customerAccount -> {                                                                 
            //declare the call to get the customer                                                    
            Mono<Customer> customerMono = Mono.just(new Customer(customerAccount));                   

            //declare the call to get the location pricing                                            
            Mono<Result<LocationPricing>> result = Mono.just(new Result<LocationPricing>());          

            //declare the call to get the location profile                                            
            Mono<LocationProfile> locationProfileMono = Mono.just(new LocationProfile());             

            //in the zip call all the services actually are executed                                  
            return Mono.zip(customerMono, result, locationProfileMono);                               
        })                                                                                            
        .map(LocationProfileInfo::new)                                                                
;                                                                                                     
公共Mono getProfileInfoByLocationAndCustomer(字符串customerId,字符串位置){ 返回Mono.just(“customerAccount”)//调用服务 .flatMap(customerAccount->{ //声明呼叫以获取客户 Mono customerMono=Mono.just(新客户(customerAccount)); //声明调用以获取位置定价 Mono result=Mono.just(new result()); //声明调用以获取位置配置文件 Mono locationProfileMono=Mono.just(new LocationProfile()); //在zip调用中,所有服务实际上都被执行 返回Mono.zip(customerMono、result、locationProfileMono); })