Возвращает ли Futures.immediateFuture (x) в API антипаттерн? - PullRequest
2 голосов
/ 24 марта 2020

Это, по-видимому, не охватывается https://github.com/google/guava/wiki/ListenableFutureExplained

Но очень распространенный шаблон

@Override
public ListenableFuture<Void> loadResources() {
  fastSyncMethod();

  return Futures.immediateFuture(null);
}

Есть ли где-нибудь указания по этому вопросу? Большая часть использования кода с использованием ListenableFutures будет зависеть от предположений, которые мы можем сделать безопасно при вызове или реализации API с использованием ListenableFuture.

Ответы [ 3 ]

4 голосов
/ 24 марта 2020

Мы не знаем, что в syncMethod, но название, похоже, выбрано для обозначения «некоторого кода синхронной связи», и в этом случае пример кода, который вы показываете, явно является антипаттерном. Я подозреваю, что это не включено в документы по гуаве просто потому, что они никогда не думали, что кто-то напишет это. Это все равно, что сказать людям не объявлять свой метод как возвращающий объект, если он на самом деле всегда возвращает null, или назвать его «doX», если это действительно Y. Подписи обещают поведение, и возвращать обещания будущего, которые вы, по крайней мере иногда, вернуть неполное будущее.

Если у вас есть метод, который иногда задерживает работу, а иногда нет, имеет смысл возвращать законченное будущее по незадержанному пути. Вот несколько рекомендаций:

  1. Рассмотрите обработку исключений вашего вызывающего: он может ожидать, что определенные типы сбоев приведут к неудачному будущему, и может неправильно обрабатывать ваш метод, вызывая исключение напрямую.
  2. Не вызывайте напрямую код, который вызывает InterruptedException. Это верный признак того, что вы нарушаете ожидания вызывающего абонента относительно того, являетесь ли вы асинхронным или нет.
  3. IOException также является красным флагом, поскольку обычно он сопровождает медленные сетевые или дисковые вызовы, которые ваш вызывающий может ожидать, что произойдет асинхронно .

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

1 голос
/ 24 марта 2020

В вашем примере показано переопределение метода, что важно здесь.

При наличии метода, возвращающего ListenableFuture, автор интерфейса или суперкласса позволяет реализациям асинхронно возвращать реализации , Аналогично, вызывающие методы знают, что допускают асинхронное возвращаемое значение.

В свою очередь, реализация обещает быть неблокирующей. Поскольку он возвращает ListenableFuture, у него есть возможность перенести любую дорогостоящую работу в фоновый поток, использовать асинхронный сетевой вызов или что-то еще.

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

Итак, является ли ваш пример антипаттерном? Это зависит от того, насколько дорогой syncMethod(). Если это быстро (не блокирует и не выполняет длительных вычислений), то пример в порядке. Если он медленный (возможно, он ожидает в сети или вычисляет очень большое число), тогда да, это антипаттерн.

1 голос
/ 24 марта 2020

My 2 c

Мне кажется, что это антипаттерн.

  • Он оставляет два кодовых пути для обработки ошибок, обязательный try {} catch {} в вызывающем коде, плюс исключения в конвейере ListenableFuture
  • Это делает время выполнения syncMethod () соответствующим тому, вызывающие могут принять метод в синхронном режиме. Для кода с высокой пропускной способностью даже запись журнала на диск или использование API InetAddress является операцией блокировки.
  • Это нарушает несколько Функциональную парадигму Futures, например, ссылочную прозрачность.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...