Здесь я пытаюсь выполнять асинхронные и неблокирующие вызовы с использованием реактора, и для каждого запроса мне, возможно, придется вызывать две службы последовательно (в моем случае ниже, getAccountInfoFromAAA
и getAccountInfoFromBBB
).
Вот мой ItemRequest
объект:
public class ItemRequest {
private Account account;
private Result firstServiceResult;
private Result secondServiceResult;
private PostingParameterCode postingParameterCode; //enum
//...
//...
//getters and setters
}
Итак, мой запрос будет содержать несколько itemRequest
с, и для каждого itemRequest
я выполняю асинхронные вызовы как:
public void getAccountData(List<ItemRequest> itemRequests) {
ImmutableList<ItemRequest> list = ImmutableList.copyOf(itemRequests);
Flux.fromIterable(list).flatMap(this::callBothSors).blockLast();
}
public Mono<ItemRequest> callBothSors(ItemRequest itemRequest) {
return getAccountDataService.getAccountDataFromAAAandBBB(itemRequest);
//here, it will enter into a sequential call for each itemRequest
}
Это мой первый интерфейс служебного вызова:
public Mono<ItemRequest> getAccountDataFromAAA(ItemRequest itemRequest);
Это мой второй интерфейс служебного вызова:
public Mono<ItemRequest> getAccountDataFromBBB(ItemRequest itemRequest);
Этот метод будет иметь до двух последовательных вызовов на основеусловие:
public Mono<ItemRequest> getAccountDataFromAAAandBBB(ItemRequest itemRequest){
Mono<ItemRequest> firstCallResult = Mono.empty();
Mono<ItemRequest> secondCallResult = Mono.empty();
if(isFirstServiceCallRequired(itemRequest)){
firstCallResult = this.firstServiceCallImpl.getAccountDataFromAAA(itemRequest);
//basically, firstService call will update the accountKey information and
//will also set the result status to OK which is required to decide
//whether to make secondService call.
} else {
//Account key is already present, so just update the result status which I need later.
Result result = new Result();
result.setStatus(Result.Status.OK);
result.setMessageText("First call not required as account info is set for item request");
itemRequest.setFirstServiceResult(result);
}
//Now, before calling the second service, I need to check the following:
if(null!= itemRequest.getFirstServiceResult() &&
itemRequest.getFirstServiceResult().getStatus().equals(Result.Status.OK) &&
itemRequest.getPostingParameterCode().equals(PostingParameterCode.MOBILECREDIT)){
secondCallResult = this.secondServiceCallImpl.getAccountDataFromBBB(itemRequest);
}
return firstCallResult.then(secondCallResult); //attaching the
//firstCallResult and secondCallResult to produce a single Mono
}
Работает нормально, когда firstCallResult
не требуется.Но когда требуется первый вызов, эта проверка состояния не пройдет, так как у меня не будет обновлен объект результата первого вызова:
if(null != itemRequest.getFirstServiceResult() &&
itemRequest.getFirstServiceResult().getStatus().equals(Result.Status.OK) &&
itemRequest.getPostingParameterCode().equals(PostingParameterCode.MOBILECREDIT))) { ... }
//this condition check will not pass because first service call is not actually executing
Оба случая работают нормально, если я добавлю следующее утверждение:
if(isFirstServiceCallRequired(itemRequest)){
firstCallResult = this.firstServiceCallImpl.getAccountDataFromAAA(itemRequest);
firstCallResult.block(); //adding this case will work on both cases
}
Но я не думаю, что получу выгоду от реакторов таким образом.Я думал о такой логике:
Mono<ItemRequest> result = firstService.call(...)
.doOnNext(/*do something */)
.then( ... secondService.call())
Но я не мог найти способ связать secondService с firstService, чтобы получить моно-результат и те же проверки условий.Проверка состояния важна, так как я не всегда хочу выполнить вторую услугу.Есть ли способ связать secondService с firstService для получения результата и проверки этих условий?
Извинения за длинный вопрос.Любые предложения / помощь будет принята с благодарностью.