Do multiple calls to different methods in parallel in spring - java

I am fetching data from several different APIs. They are rest and soap web services. I have one id that I pass to each API one by one and get data in return. But each API takes few seconds to return the result and so the final response object that I create takes too much time.
My application is a Spring 4 Rest Service. What is the best way to call all these several APIs in parallel so that my Response time reduces to as less as possible.
Thanks.

You can use #Async annotation. You can find an example here

Daniel's answer is right but I would like to add something more to it. If you want to do something with your results but don't want to block with Future#get then I would suggest you to use CompletableFuture class.
It will let you add various actions which will be triggered on its completion.
There is also a really nice article on how to use CompletableFuture with Spring's #async annotation. Here it the link. Completable futures with Spring async

Related

Does applying Pagination on response using Spring Webflux make it blocking?

Does the following code block the call, if so how do I make it non-blocking? i.e. making the use of Reactive Java Stream useless? How can I paginate without making the call blocking?
Currently I have a webClient calling to a backend service that returns a Flux<Item> and according to specs I need to return a ResponseEntity<ItemListResponse> where I have provide a paginated response
code inside the controller method looks like ->
// getItems method was initially returning a Flux but my method was failing to paginate it so now that method returns a Mono<List<Item>>
// I would really like to see how I can make this work with Flux!
return webClient.getItems(...required params...)
.map(r -> {
// we get offset and limit from query params
var paginatedItems = listPaginator.applyPagination(r, offset, limit)
// assembleItemResponse method maps all values from backend service to new response required by client
List<ItemResponse> itemResponseList = paginatedItems.stream()
.map(this::assembleItemResponse)
.collect(Collectors.toList());
return ResponseEntity.ok()
.body(ItemListResponse.builder()
.itemCount(r.size())
.pagesize(itemResponseList.size())
.listItems(itemResponseList)
.build());
});
Does applying Pagination on response using Spring Webflux make it blocking?
There's nothing inherently blocking about pagination, but the normal Spring Data way to achieve that is by using a PagingAndSortingRepository to query the data layer for only the results you need for that particular page (as oppose to querying the data layer for all possible results then filtering, which could have a huge performance impact depending on the data size.) Unfortunately that approach is blocking. The PagingAndSortingRepository doesn't as of yet have a reactive equivalent.
However, that doesn't appear to be what you're doing here. A complete example here would be helpful, but it looks like r is a list of items, and then you're applying a listPaginator to that entire list to reduce it down. If that's the case then there's no reason why it would necessarily be blocking, so it should be safe. However, it's impossible to say for certain without knowing the specific behaviour of the applyPagination and assembleItemResponse methods. If those methods are blocking then no - you're not safe here, and you need to consider another approach (exactly what approach would require a more complete example.) If those methods are non-blocking (they just deal with the data they have, don't call any further web / db services, etc.) then you're ok.
Separately, you might consider looking at Blockhound which will be able to tell you for certain whether you have any blocking calls where they shouldn't be.

Is there some functionality to log/calculate time latencies of modules in spring weblfux? For e.g. using #Timed annotation

I would like to know is there, or can we make use of any functionality to log the actual time taken by a function returning Mono/Flux? For example something like creating a #Timed annotation to log the actual time taken by it.
I know the function return type being Flux/Mono, so it should return immediately so that is why I wanna know if we can actually do something like this so that we can know which modules/sub-modules are taking how much time?
We want to migrate our blocking spring-boot service to spring webflux, so going through all the possible options we have for better understanding.
P.S. I am new To reactive programming, still learning the paradigm.
You can use metrics() operator to time a publisher. You can combine this with the name() and tags() operators to customise the metrics that get published.
listenToEvents()
.name("events")
.tag("source", "kafka")
.metrics()
.doOnNext(event -> log.info("Received {}", event))
.delayUntil(this::processEvent)
.subscribe();
Publisher metrics docs

How to name Span in Spring Sleuth in a reactive calling chaining

I have Spring Cloud Sleuth (2.0.2.RELEASE) working within a (partially) reactive class in some web based request/response system. The code is something like this:
private static final Scheduler PROCESSING_SCHEDULER = Schedulers.newParallel("processingScheduler");
public Set<ProcessedItem> processItems(List<Item> incomingItems) {
return Flux.fromIterable(incomingItems)
.publishOn(PROCESSING_SCHEDULER)
.collectMultimap(Item::getRequestIdentifier)
.flatMapIterable(Map::values)
.flatMap(itemProcessor::processGroupedItems)
.collect(Collectors.toSet())
.block();
}
As there are quite many responses coming in all the time, this method is being called several hundreds of times for one single request.
I suspect that this call with the .publishOn leads to hundreds and thousands of async spans in Zipkin (see attached screenshot). At least I assume that the spans are from that because it is what I understand from the documentation
So my first question would be:
How can I associate a name for such async threads? I don't have a place to put #SpanName here.
As a follow up, is there any way to NOT collect these spans? I don't need them, they fill up our Zipkin storage, but I also don't want to disable reactive or Sleuth in general since it is needed in other places ...
Screenshot from Zipkin
You can create your own custom SpanAdjuster that will modify the span name. You can also use FinishedSpanHandler to operate on finished spans to tweak them.

spring mvc: the difference between DeferredResult and ListenableFuture?

Spring MVC lets controllers return DeferredResult and ListenableFuture (which is implemented by ListenableFutureTask) to do async response. What's the difference? When should I use each of them?
They are conceptually similar to each other and can be used interchangeably as a controller's method result, thanks to ListenableFutureReturnValueHandler that adapts the second to the first one.
However, both DeferredResult class and ListenableFuture interface come from two different worlds:
First from org.springframework.web.context.request.async package added in version 3.2.
Second from org.springframework.util.concurrent package available since 4.0.
Moreover, they were added for different needs. While the first one provides a base and complete functionality for providing controller's result asynchronously, the second one allows you in addition to bridge your implementation with already existing classes/frameworks, like for example ExecutorService framework (see ListenableFutureTask).
So the bottom line is, use the DeferredResult class when it's enough for you to implement further processing on your own or ListenableFuture when you'd like to use ExecutorService-like frameworks.
DeferredResult is an alternative to Callable that allows you to produce a result. You can also extend DeferredResult to associate additional data or behavior, in case you need to access some data later without needing additional data structures. But that's about it.
ListenableFuture future comes in handy when you need to add callbacks to the asynchronous task. Guava's ListenableFuture actually allows for composition, which I don't see Spring's ListenableFuture to do.
For that you'd rather use CompletableFuture, which is also supported by Spring.
You can compose futures very simply, check this out: http://www.deadcoderising.com/java8-writing-asynchronous-code-with-completablefuture/

Can you use Future/Futuretask objects with Spring TaskExecutors?

Is it possible to use Java FutureTask with a Spring TaskExecutor to get a Future object?
I'm looking for a TaskExecutor that implements the Java ExecutorService interface, in particular the submit() method. Looking through the Spring Javadocs doesn't reveal any classes like this. Is there some alternate method to handle futures through Spring TaskExecutors that I am unaware of?
If it is possible, could you also include an example?
Spring 3 has added submit methods with support for Future objects to AsyncTaskExecutor. Until then if you want access to Future objects I think you will need to get the underlying JDK executor (e.g. using getThreadPoolExecutor) and submit tasks directly on that.

Categories

Resources