Reactive Usage
Updated at 1709797385000Overview
EzyPlatform is designed to limit the usage of join
statements. Therefore, it requires a programming approach that utilizes multithreading to call and gather data concurrently, optimizing performance. The answer to this lies in Reactive.
In EzyPlatform, Reactive is a programming library that allows simultaneous execution of processing functions and aggregates the data once all the functions are processed. Although it may seem extensive as a library, when using it, you only need to focus on the Reactive class.
Usage
Reactive can be used in two ways: multiple and single.
Multiple
Multiple allows registering processing functions mapped to a key, with the goal of retrieving results when all functions have been called, for example:
return Reactive.multiple() .register( "mediaMap", () -> mediaIds.isEmpty() ? Collections.emptyMap() : mediaService.getMediaNameMapByIds(mediaIds) ) .register( "productPriceMap", () -> productPriceService .getProductPriceMap( productIds, currencyId ) ) .mapBegin(map -> { Map<Long, MediaNameModel> mediaMap = map.get("mediaMap"); Map<Long, ProductPriceModel> productPriceMap = map.get("productPriceMap"); return pagination.map(it -> { long productId = it.getProductId(); ProductModel product = productById.getOrDefault( productId, ProductModel.builder().build() ); ProductPriceModel price = productPriceMap.getOrDefault( productId, ProductPriceModel.ZERO ); return bookStoreModelToResponseConverter.toResponse( it, product, mediaMap.get(product.getId()), price, currencyFormat ); }); }) .blockingGet();
- The
register
method is used to register a regular result-returning function. - The
registerRx
method is used to register anRxOperation
orRxMultiple
result-returning function. - The
blockingGet
method will wait until all component functions have finished execution before proceeding.
Single
Single is more suitable when you only want to process a single piece of data or a list of data. In fact, it is a wrapper for RxMultiple
to make the usage of Reactive
simpler. Therefore, this class will also be used less frequently, for example:
Reactive.single(value) .operateItem(consumer) .blockingExecute(); List<String> actual = Reactive.single(values) .mapItem(String::valueOf) .blockingGet();
Note
For functions that use Reactive blocking internally, they should not be registered with the external Reactive, for example:
public void hello() { Reactive.multiple() .register( "postTitleMap", () -> postService.getPostTitleMapByIds(postIds) ).blockingGet(); } Reactive.multiple() .register( "postTitleMap", () -> hello() )
Since Reactive uses a single thread pool, calling blocking functions internally can cause thread starvation, and the external function may be indefinitely waiting.
Example source code
You can take a look here.