powered by simpleCommunicator - 2.0.30     © 2024 Programmizd 02
Map
Форумы / Java [игнор отключен] [закрыт для гостей] / Очень много CompletableFuture
25 сообщений из 50, страница 1 из 2
Очень много CompletableFuture
    #39939885
bob1970
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
На новом проекте встретил очень частое использование CompletableFuture. "Частое" это слабо сказано, почти сплошняком. Проект - типичный rest со spring внутри. CompletableFuture используется везде: в контроллерах, сервисах, репозиториях. Почти все методы возвращают или принимают CompletableFuture. Может это и нормально, но как-то непривычно.
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939888
bob1970
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Уточнение. Почти все методы возвращают или принимают CompletableFuture/
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939895
bob1970
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Или это какой-то новый стиль программирования и все что касается работы с ресурсами (базы, файлы и т.п.) нужно делать через CompletableFuture.
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939902
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bob1970
Или это какой-то новый стиль программирования и все что касается работы с ресурсами (базы, файлы и т.п.) нужно делать через CompletableFuture.

Все правильно, это пародия на функциональное программирование, но увы из-за долгой истории java эти концепты не получается сделать красиво и на мой взгляд код становится просто п..ц
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939923
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bob1970,
Сабж служит для удобного асинхронного кодирования.
Вопрос, нужна ли асинхронность при БАНАЛЬНОМ REST?
Мое имхо - не нужна.
Платформа java и контейнер аппСервера сделали все чтобы прогер не задумывался о потоках и асинхронности.
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939929
bob1970
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PetroNotC Sharp
bob1970,
Сабж служит для удобного асинхронного кодирования.
...

Видел бы ты это удобно. Мозг в трубочку сворачивается. Представь себе код, где обычные объекты практически не используются, все завернуто в CompletableFuture. Я не против CompletableFuture. Все правильно. И удобно, и производительность. Но где грань применимости? Понятно что при обращении к внешним медленным ресурсам, и тогда получается что правильно запросы к БД нужно делать через CompletableFuture. Как-то бы определить эту границу.
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939934
Андрей Панфилов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bob1970
Все правильно. И удобно, и производительность. Но где грань применимости? Понятно что при обращении к внешним медленным ресурсам, и тогда получается что правильно запросы к БД нужно делать через CompletableFuture. Как-то бы определить эту границу.
В чем правильность-то? Со стороны производительности вообще не имеет никакого смысла переносить выполнение кода в другой поток, потому что как коду для выполнения нужен был поток, так и он и остался нужен, а накладные расходы при этом увеличиваются - контекст же еще нужно между потоками таскать.
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939943
bob1970
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Андрей Панфилов,

Удобно/неудобно. Размышляю пока. Почему выбрано такое решение. Вот пару ссылок:
CompletableFuture : A new era of asynchronous programming Сама статья ниочем, но заголовок внушает.

И другая
Synchronous or asynchronous, and why wrestle with wrappers?
Может и в самом деле ушла эра синхронного программирования.
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939947
Андрей Панфилов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bob1970
Может и в самом деле ушла эра синхронного программирования.
Нет, это просто нашли лоха-заказчика и выдали ему дичь за прорывную технологию.
Вот для просветления: Чем асинхронные сервлеты отличаются от Sping WebFlux
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939949
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bob1970,

мы-же кода не видели. Вполне возможно что существует кейс когда асинхронные микро-задачки
удобны. Как-по мне - не очень. Неудобно отслеживать статус ошибки. Если у тебя вся логика
- короткая и отбивается одним методом рест-контроллера - тогда ручная CompletableFuture - не
имеет смысла. Сам рест-контроллер и так обеспечивает множество конкурирующих сеансов.

Чтобы понять что CompletableFuture являлся ненужным обвесом - надо взять полностью этот
проект и переписать на классической rest архитектуре и просто посмотреть как оно вышло.
Возможно кода станет меньше.
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939953
bob1970
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mayton

мы-же кода не видели.

Там страшно. Очень.

mayton
Вполне возможно что существует кейс когда асинхронные микро-задачки
удобны.

Именно. Меня бы не смутили мелкие вставки, обращения к микро=задачкам. Но когда все. Сплошь. Маленький пример:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
public interface IBaseRepository<TEntity, TFilter> {
    CompletableFuture<List<TEntity>> getRange(@NotNull TFilter filter);
    CompletableFuture<TEntity> getItem(@NotNull Object id);
    TEntity getItemReference(@NotNull Object id);
    CompletableFuture<List<TEntity>> getAll(@NotNull TFilter filter);
    CompletableFuture<Long> count(@NotNull TFilter filter);
    CompletableFuture<Void> update(@NotNull TEntity entity);
    CompletableFuture<Void> add(@NotNull TEntity entity);
    CompletableFuture<Void> remove(@NotNull TEntity entity);
    CompletableFuture<Void> update(@NotNull List<TEntity> items);
    CompletableFuture<List<TEntity>> add(@NotNull List<TEntity> items);
    CompletableFuture<Void> remove(@NotNull List<TEntity> items);
}


Это базовый репозиторий. Как можно понять все остальные репо-ии наследуются. Сервисы , контроллеры в том же духе. Ну и можете представить implementation.

mayton

Чтобы понять что CompletableFuture являлся ненужным обвесом - надо взять полностью этот
проект и переписать на классической rest архитектуре и просто посмотреть как оно вышло.
Возможно кода станет меньше.

Это нереально. Очень много кода.

В общем-то тему, наверное, нужно переименовать в Реактивная Java и закрыть. А решать каждый для себя.
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939955
Андрей Панфилов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bob1970,

а как при таком контракте репозитория хоть какую-то бизнес-логику организовать (ну банально: записать информацию о транзакции и списать сумму со счета)? или там CRUD и ничего больше?
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939957
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bob1970
Видел бы ты это удобно.
я во второй части ответа как раз и выдвинул тезис, что это не удобно.
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939958
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если рассмотреть такой упрощенный круд-реп

Код: java
1.
2.
3.
4.
public interface IBaseRepository<TEntity, TFilter> {
    TEntity getItemReference(@NotNull Object id);
    CompletableFuture<Void> add(@NotNull TEntity entity);
}



И я допустим хочу с ним поработать. Я добавил документ entity.
И вызываю сраз-же getItemReference.

Код: java
1.
2.
baseRepository.add(enity);
TEntity entity = getItemReference(entity.getId);


И во второй строке я получаю ошибку или исключение. Мой фьючерс еще не завершил работу.
Тоесть я видимо как-то не так работаю. Очевидно чтобы гарантировать что причинно-следственная
цепочка отработала я должен ставить искусственный барьер на первый и второй фьючерс.
И усложнять простой и очевидный код. И теперь вопрос. Ради чего это делалось?
И ведь это даже не CQRS. В той методике есть хотя-бы темпоральная хронология
в КОМАНДАХ. Команда которая дана раньше - раньше будет исполнена. Но только не здесь.

Почему нельзя было просто сделать так?

Код: java
1.
2.
3.
4.
public interface IBaseRepository<TEntity, TFilter> {
    TEntity getItemReference(@NotNull Object id);
    void add(@NotNull TEntity entity);
}
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939959
bob1970
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Андрей Панфилов,
Примерно так:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
    @Override
    public CompletableFuture<Void> add(@NotNull TEntity entity) {
        return CompletableFuture.runAsync(() -> {
            EntityManager entityManager = factory.createEntityManager();
            try {
                EntityTransaction transaction = entityManager.getTransaction();
                try {
                    transaction.begin();
                    entityManager.persist(entity);
                    transaction.commit();
                } catch (Exception ex) {
                    transaction.rollback();
                    throw ex;
                }
            } catch (Exception ex) {
                LOGGER.error(this.getClass().getName() + " add item error ", ex);
                throw ex;
            } finally {
                entityManager.close();
            }
        }, executor);
    }



И повторюсь -там не только CRUD. Там ВСЕ. Вообще ВСЕ. Сервисы с бизнес-логикой, контроллеры и прочий код. Все на future
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939961
bob1970
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PetroNotC Sharp,
Сравни
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
class Synchronous {
    // I/0 operations: blocking, synchronous
    <T> T fetchFromDb(Class<T> entityClass, long id) { return null; }
    String sendHttpGet(String url) { return null; }
    void sendEmail(String to, String content) { }

    // the business logic: synchronous
    void runBusinessProcess() {
        User user = fetchFromDb(User.class, 42);
        String profile = sendHttpGet(
            "http://profile_service/get/" + user.getProfileId());
        sendEmail(user.getEmail(), "Your profile is: " + profile);
    }
}



и

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
class Wrappers {
    // I/O operations: non-blocking, asynchronous
    <T> CompletableFuture<T> fetchFromDb(Class<T> entityClass, long id) { return null; }
    CompletableFuture<String> sendHttpGet(String url) { return null; }
    CompletableFuture<Void> sendEmail(String to, String content) { return null; }

    // the bussines logic: asynchronous
    CompletableFuture<Void> runBusinessProcess() {
        // thenCompose: also known as flatMap, combines two futures
        return fetchFromDb(User.class, 42).thenCompose(user -> {
            // storing the intermediate result in variables
            CompletableFuture<String> httpResult = 
              sendHttpGet("http://profile_service/get/" + user.getProfileId());
              
            return httpResult.thenCompose(profile ->
                    sendEmail(user.getEmail(), "Your profile is: " + profile));
        });
    }
}



Это отсюда
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939963
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как будто-бы калька с другого фреймворка. Может даже не на Java а на другом языке или технологии
где такие штуки красиво заворачиваются в аспекты или лябды. Здесь как-бы мясо вот серединке

Код: java
1.
2.
3.
transaction.begin();
entityManager.persist(entity);
transaction.commit();


А сверху и снизу просто одинаковые обёртки которые обеспечивают трансфер in/out параметров.
Вот почему мне и напомнило аспекты.
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939964
bob1970
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mayton,

Да, это главное. Но как завернуто
Код: java
1.
2.
3.
return CompletableFuture.runAsync(() -> {
...
 }, executor);
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939965
Андрей Панфилов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bob1970

Примерно так:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
    @Override
    public CompletableFuture<Void> add(@NotNull TEntity entity) {
        return CompletableFuture.runAsync(() -> {
            EntityManager entityManager = factory.createEntityManager();
            try {
                EntityTransaction transaction = entityManager.getTransaction();
                try {
                    transaction.begin();
                    entityManager.persist(entity);
                    transaction.commit();
                } catch (Exception ex) {
                    transaction.rollback();
                    throw ex;
                }
            } catch (Exception ex) {
                LOGGER.error(this.getClass().getName() + " add item error ", ex);
                throw ex;
            } finally {
                entityManager.close();
            }
        }, executor);
    }

Это же реализация репозитория, причем посредственная, я же спрашивал как организовать бизнес-логику, когда нужно два репозитория использовать.
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939966
bob1970
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Андрей Панфилов,
Примерно так
Код: java
1.
2.
3.
4.
5.
6.
7.
        CompletableFuture task1 = callService1(context);
        CompletableFuture task2 = callService2(context);

        return CompletableFuture
            .allOf(task1, task2)
            .thenCompose(nop -> callService3(context))
            .thenApply(nop -> callService4(context)).getResult());
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939967
Андрей Панфилов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bob1970
Примерно так
Код: java
1.
2.
3.
4.
5.
6.
7.
        CompletableFuture task1 = callService1(context);
        CompletableFuture task2 = callService2(context);

        return CompletableFuture
            .allOf(task1, task2)
            .thenCompose(nop -> callService3(context))
            .thenApply(nop -> callService4(context)).getResult());

А на ACID забить?
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939968
bob1970
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Андрей Панфилов
А на ACID забить?

Оххх... Там до таких страшных слов, как до Китая.
А вообще, я не про конкретный проект. Я про подход. Реактивная Java есть и используется. И похоже использовать ее нужно как-то так. Короче, надо изучать это дело.
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939969
bob1970
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mayton

Почему нельзя было просто сделать так?

Код: java
1.
2.
3.
4.
public interface IBaseRepository<TEntity, TFilter> {
    TEntity getItemReference(@NotNull Object id);
    void add(@NotNull TEntity entity);
}



Это самый главный вопрос.
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939990
andreykaT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bob1970
Или это какой-то новый стиль программирования и все что касается работы с ресурсами (базы, файлы и т.п.) нужно делать через CompletableFuture.

ты прям плей фреймворк описал ))) в нем тоже все возвращает футуры. все что связано с взаимодействием со сторонними сервисами или ресурсами (бд, веб, акторы и тп)
...
Рейтинг: 0 / 0
Очень много CompletableFuture
    #39939991
andreykaT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bob1970
PetroNotC Sharp
bob1970,
Сабж служит для удобного асинхронного кодирования.
...

Видел бы ты это удобно. Мозг в трубочку сворачивается. Представь себе код, где обычные объекты практически не используются, все завернуто в CompletableFuture. Я не против CompletableFuture. Все правильно. И удобно, и производительность. Но где грань применимости? Понятно что при обращении к внешним медленным ресурсам, и тогда получается что правильно запросы к БД нужно делать через CompletableFuture. Как-то бы определить эту границу.

дело привычки. мозг перестает скручиваться в трубку если ты постоянно тащишь все через функторы монады (мап флатмап или зенкомпос зенаплай вроде). да. это асинхронка, но вот мне лично кажется, что в этих кишках ошибки ловить прям отдельный челлендж. особенно когда проблемы возникают с многопоточкой. а они возникают. кто говорит нет - тот обманывает.

другая проблема. у джавы комплитабл фьюча выглядит как гамно. в скале лучше. в ней хоть форкомпрехеншн есть который отображает это не в таком идиотском виде.
...
Рейтинг: 0 / 0
25 сообщений из 50, страница 1 из 2
Форумы / Java [игнор отключен] [закрыт для гостей] / Очень много CompletableFuture
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]