Вы здесь:

Интересно было узнать о возможностях CompletableFeature.
Проект и описание находится тут https://github.com/cherepakhin/completablefeature_many_benchmark

    ExecutorService executorService = Executors.newCachedThreadPool();

    String getContext() {
        return StringUtils.repeat("-", 1000);
    }

    // Имитация работы какого-то внешнего сервиса
    void sleep() {
        try {
            TimeUnit.MILLISECONDS.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @GetMapping("/")
    public String trivial() {
        sleep();
        return getContext();
    }

    @GetMapping("/simple")
    public CompletableFuture simple() {
        return CompletableFuture.supplyAsync(() -> {
            sleep();
            return getContext();
        }, executorService);
    }

    @GetMapping("/nested")
    public CompletableFuture nested() {
        return CompletableFuture.supplyAsync(() -> {
            return CompletableFuture.supplyAsync(() -> {
                        sleep();
                        return getContext();
                    },executorService
            );
        },executorService).get();
    }

Ниже описаны только итоги.

Нагрузка во всех вариантах 500rps

Схема кэширования Среднее время ответа (мс) К-во тредов (шт) Память (Мб)
Без CompletableFeature 5 000 229 150
С CompletableFeature Executors.newCachedThreadPool() 1 000 847 ~230
Кол-во выделяемых сервисом тредов меньше нагрузки (нагрузка 500 rps, а тредов выделено 100) . CompletableFeature executorService = Executors.newFixedThreadPool(100) >10 000 188 200-350

 

С CompletableFeature время ответа сократилось аж в 5 раз! Но, увеличился расход памяти. Неоднозначные результаты в третьей строке (Кол-во выделяемых сервисом тредов меньше нагрузки).

И все таки насколько ценен CompletableFeature? Какую проблему мы решаем, используя это решение? Может быть лучшие результаты даст кеш или оптимизация самих сервисов? По своему опыту скажу, что разработка, тестирование с CompletableFeature, мягко говоря, имеет свою специфику. Возвращая CompletableFeature в методе, вы принуждаете клиента его обрабатывать и перекладывете проблему дальше, и кому-то все-равно придется ее разрулить. Если уж решили использовать CompletableFeature, то сам его тут же и разруливай. Грубо говоря, это локальное(техническое) решение, на уровне приватных методов класса. Не должно путаться в бизнес логике. Остальные классы не должны быть замешаны в эту кашу. Еще большие сомнения, использование CompletableFeature в Spring окружении, т.к. Spring сам решает эту проблему.