Интересно было узнать о возможностях 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 сам решает эту проблему.
O CompletableFeature
https://www.baeldung.com/java-completablefuture