Reactive Usage

Updated at 1690883490000

Overview

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(
        "postTitleMap",
        () -> postService.getPostTitleMapByIds(postIds)
    )
    .registerRx(
        "postSlugMap",
        postSlugService.getLatestSlugMapByPostIds(postIds)
    )
    .blockingGet(map -> {
        Map<Long, String> postTitleMap = map.get("postTitleMap");
        Map<Long, String> postSlugMap = map.get("postSlugMap");
        return newArrayList(models, it ->
            modelToResponseConverter.toRecentCommentResponse(
                it,
                postSlugMap.get(it.getPostId()),
                postTitleMap.get(it.getPostId())
            )
        );
    });
  1. The register method is used to register a regular result-returning function.
  2. The registerRx method is used to register an RxOperation or RxMultiple result-returning function.
  3. 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.