• «Восстание машин» часть 1: continuous delivery для базовых Docker образов
    0

    А http://buildpacks.io рассматривали?

  • Эффективные надежные микросервисы
    +1

    Если я правильно понял статью (после чтения по диагонали), то у вас используется:


    • Сервисы связаны в кластер
    • Шардирование
    • Local queries / reads
    • State replication
    • Recovery через репликацию данных с других инстансов

    Что делается "из коробки" (правда подозреваю менее эффективно, хотя интересно было бы сравнить) в Akka с помощью Akka Cluster + Akka Persistence и ещё пары штук возможно.


    P.S. Олег, ты чего на "вы", не первый день знакомы ;)

  • Эффективные надежные микросервисы
    +1

    Выглядит как своя реализация идей, доступных в Akka. Рассматривали её?

  • Как собрать образ Oracle DB для Testcontainers
    0

    С reusable containers Ryuk не будет прибивать контейнеры которые помечены как reusable, в том и смысл :)

  • Как собрать образ Oracle DB для Testcontainers
    0

    Начиная с Testcontainers 1.12.3, мы добавили "reusable containers", что позволяет переиспользовать контейнер между сессиями тестов при локальной разработке.


    Так что теперь не обязательно использовать другой тул :)

  • R2DBC Arabba-RELEASE — новый взгляд на реактивное программирование для SQL
    +1

    За репорт — респект!
    Про "мультитредовые тесты" — надеюсь тоже репортил.


    По ссылке на TechEmpower (который я кстати не очень люблю, учитывая что он был создан чтобы показать какой их фреймворк быстрый и ни раз был замечен делающим некорректные бенчмарки для других) r2dbc не нашёл.
    Опять же, стоит мерять производительность реальных реактивных сервисов (JDBC + Thread Pool vs R2DBC), где каждый вызов JDBC будет идти через context switch т.к. блокировать текущий реактивный поток нельзя.


    В "песочнице" R2DBC vs JDBC показывает себя неплохо (особенно с MSSQL, кстати), а так же есть куда оптимизировать. В таких вещах обычно первым идёт "сделать чтобы работало" а потом уже "чтобы быстро".

  • R2DBC Arabba-RELEASE — новый взгляд на реактивное программирование для SQL
    +2

    А не поделитесь ссылками чтобы подтвердить своё мнение? На открытые баг репорты, бенчмарки.


    А то иначе выглядит как вброс ;)

  • R2DBC Arabba-RELEASE — новый взгляд на реактивное программирование для SQL
    +1

    Конечно, конечно… нет :D
    Файберы и корутины упрощают для юзера, а реактивщина — делает чтобы быстро было!
    Одно другому не мешает ;)


    ИМХО файберы виртуальные потоки только улучшат adoption реактивных технологий — потому что можно будет не бояться "что-то там заблокировать", а всякие flatMap concatMap превратятся в обычный map.

  • Из Groovy ушёл Cédric Champeau‏
    0

    Как опытный Jenkins-овод, могу заверить:
    1) "Groovy не работают в некоторых местах" — это скорее бага, чем особенность, которую они так и не смогли побороть
    2) "тратить часы чтобы понять как оно вообще собирается и кто кого зовет" — так же применимо к Jenkinsfile-ам, иногда даже ситуация гораздо хуже, чем в Gradle.
    3) "структуру можно полностью переопределить" — это не совсем так. В Gradle действительно можно "пачкать" variable scope, но нельзя, например, переопределить "configurations {}" блок, в итоге имеем структурированность практически как в декларативном Jenkinsfile-е
    4) "stages" в Jenkinsfile только если использовать декларативный подход, он не всегда подходит, приходится использовать императивный, и там ад и содомия похлеще Gradle файлов

  • Из Groovy ушёл Cédric Champeau‏
    0
    зачем он весь (и Groovy вместе с ним) нужен

    Так как уже есть jenkins pipeline

    А ничего что Jenkinsfile это Groovy?:)

  • Строители против синтаксиса Java
    0

    Надо знать только этот класс, и на нём будут все методы.


    И только в этом билдере в статье есть pantonymic

    Не совсем. Юзер просто использует $DesiredUserType.Builder и видит все поля, которые можно "настроить" с помощью билдера.
    Т.е. пользователь не ищет "а где же настроить pantonymic", он имеет тип, и видит какие параметры этого типа можно установить.

  • Строители против синтаксиса Java
    0

    Значительно упрощенный API благодаря этому.
    Юзеру не надо знать о всех существующих билдерах, не надо знать в каком из них настаривается foo, а в каком — bar (типичная проблема композиции).

  • Строители против синтаксиса Java
    +1
    Выделите все поля, которые должны быть во всех потомках, в отдельный дата-класс

    Это уже не "наследование".

  • Строители против синтаксиса Java
    0

    1) дублирование объявлений полей
    2) Да.

  • Строители против синтаксиса Java
    –4
    data class RussianUser(override val firstName: String, override val lastName: String, val patronymic: String): User()

    Даже ваш великий Котлин не спасает от тонны ненужного синтаксиса здесь. Особенно когда таких полей десятки.

  • Строители против синтаксиса Java
    +1
    и никаких new

    по-моему в вашем примере кол-во "new" удваивается при добавлении нового наследника ;)


    А когда пропертей десятки, то такой код начинает пугать. И ещё, у него есть один важный недостаток — при добавлении метода в базовый класс, он не попадает в наследников пока его вручную везде не добавят.

  • Строители против синтаксиса Java
    0

    Тогда это уже не называется "наследование"

  • Строители против синтаксиса Java
    0

    Рассматривали.


    С таким очень сложно работать, нет нормального способа хранить состояние (например, коллекции открытых портов, или переменных окружения), ну и не очевидный способ создания через прокси и вот это вот всё (в PR кстати чуть по-другому это решили)

  • Строители против синтаксиса Java
    0

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

  • Строители против синтаксиса Java
    +1
    class MyTag extends Tag {}
    
    MyTag tag = new MyTag().setId("yo"); // <-- Error!

    Летали. Знаем.

  • Строители против синтаксиса Java
    0

    Такой подход реализуется аннотацией @Wither в Lombok-е, но, к сожалению, не подходит для унаследованных сущностей.

  • Строители против синтаксиса Java
    0

    Думали про такой вариант. Неплохой, но отпал т.к.
    1) ухудшается API discoverabilitiy — надо знать какой из apply дёрнуть чтобы настроить firstName, вместо .builder().firstName()
    2) если наследование глубже 1 класса, то вообще страшно выходит
    3) лямбду нельзя на инстанс "забиндить"

  • Строители против синтаксиса Java
    +2

    Я готов все свои карма поинты обменять на плюсы к Вашему комментарию, это просто прекрасно!

  • Строители против синтаксиса Java
    +1

    мы это конечно же добавим в будущем, просто хотел поделиться быстрым workaround-ом :)

  • Строители против синтаксиса Java
    0

    параметров может быть не 3, а 30.

  • Строители против синтаксиса Java
    0

    LocalStackContainer наследуется же от GenericContainer, можно любую env variaible указать с помощью .withEnv("FOO", "BAR").

  • Строители против синтаксиса Java
    0

    Самое забавное — в моём личном опыте сложней всего для поддержки проекты доставались именно от товарищей, которые пропагандируют "правильные" способы, пишут на Java как на Scala, а ночью под подушкшой читают куски Haskell кода.
    Так что думаю тут знаний "мудрейших" не достаточно, и надо уметь их применять там, где оно уместно, и если что-то можно сделать проще — то почему бы и нет?

  • Строители против синтаксиса Java
    0

    как пользователь, мне б это не понравилось, и вот почему:
    1) API discoverability — если я хочу настроить порт, то мне надо знать наперёд в каком из билдеров этот метод для настройки порта указан
    2) многословность — в вашем примере вы по сути дела устанавливаете 3 параметра, но при этом код нагружен .builder(), .build() и их друзьями
    3) результат .build() должен содержать параметры всех "билдеров" (к сожалению в вашем примере это невозможно продемонстрировать), и, если это был билдер BarBuilder, то результат должен быть знать о свойствах Bar, а не только Foo

  • Строители против синтаксиса Java
    0

    в Spring Security норм, но им можно — у них не используется возвращаемый результат их DSL :)


    Но даже если и адаптировать его под этот случай — DSL становится сложней читать из-за обилия .and()

  • Строители против синтаксиса Java
    +1
    оказывается не про корректную архитектуру приложения

    Внезапно то как!


    Ему не удобно

    Мне удобно было бы вообще не иметь public API. Нет API — нет проблем. Клаааас.

  • Строители против синтаксиса Java
    0

    Продублирую мой ответ из твиттера:
    SuperBuilder работает только если код и сторонние библиотеки к этому коду используют Java и Lombok. В нашем случае это не всегда так.

  • Строители против синтаксиса Java
    0

    Я до сих пор удивлён что никто не упомянул трюк с .and() как это делает Spring Security:
    https://docs.spring.io/spring-security/site/docs/current/reference/html/jc.html#jc-httpsecurity

  • Строители против синтаксиса Java
    +1

    Ух ты как Java изменилась при Собянине


    Допустим, я прочитал Ваш код. Но он не отвечает на вопрос! Как сделать удобный API для всего этого, чтобы пользователям было удобно?


    Вас сразу выдаёт то, что вы приводите примеры объявления классов, а не пример их использования.
    Когда мы у себя проектируем API наших DSL, мы начинаем с "как пользователь, я хочу использовать это вот так", а потом ищем варианты как это реализовать, на грани с возможностями языка, с учетом наших пользователей. А уже потом думаем, чтобы это ещё было поддерживаемо и читаемо.

  • Строители против синтаксиса Java
    0

    Оно потому и "подойти иначе". Мы долго боролись за chaining, что забыли что есть другие способы, и что без него можно сделать вполне читаемый вариант :)

  • Строители против синтаксиса Java
    +1

    Это примерно то, что у нас сейчас (и в статье описано в секции про generic версию, только без 2х классов).
    Такой подход имеет место быть (так например работает SuperBuilder в Lombok на сколько знаю), но, к сожалению, он очень тяжело даётся контрибьюторам в проект, особенно рекурсивные конструкции вида <SELF extends MyClass>.

    Это, кстати, очень интересная тема. Одно дело — умные книжки про как можно и нельзя, а другое — как потом с таким кодом работать, особенно в OSS, где каждый контрибьютор важен.
    Разработчики Testcontainers тоже не глупые и тоже разные книжки читали, но, как и во всём — лучшее враг хорошего :)

  • Строители против синтаксиса Java
    +4

    Не совсем решаемо — аргументы конструктора не именованны и читать вызовы конструкторов с 10 параметрами — то ещё развлечение

  • Строители против синтаксиса Java
    +1

    там внизу в комментарии есть problem definition. Ваш "идеальный" код никто не станет использовать, потому что он громоздкий и неудобный (по крайней мере в той библиотеке что я описываю).


    Поэтому я и предлагаю переубедить, с примерами кода, иначе ваши комментарии выглядят как "я прочитал книжку, вы всё делаете неправильно, а я — умный".

  • Строители против синтаксиса Java
    0

    Пример:


    Есть проект — Testcontainers. В нём есть базовый класс GenericContainer.
    Есть наследники типа KafkaContainer.
    Есть даже промежуточные наследования: MySQLContainer -> JDBCContainer -> GenericContainer.


    Должна быть возможность их конфигурировать, чтобы удобно, красиво и вот это вот всё.
    Как бы вы решили эту проблему на ровном месте? :)

  • Строители против синтаксиса Java
    0

    А можно с примерами Java кода?

  • Строители против синтаксиса Java
    +1

    А, да, тут абсолютно согласен.


    Я там в конце статьи попытался написать "не стоит использовать везде", но такое стоит повторять — этот трюк не везде применим и может сделать больно в неправильных местах (capturing, serialization, classloading, вот это вот всё), особенно в production коде.


    А вот для Testcontainers пока что выглядит очень даже норм :) Но всё ещё думаем...