Pull to refresh
5
0
Send message

Пару лет назад попался обзор на Зевса, там домики строились буквой Г. После чего я прошёл все компании на максимальной сложности. Одна из любимых игр детства.

Вижу граф - ставлю лайк. Хабр, добавите такую фичу? Интересно посмотреть как бы выглядел подграф с "java" или "spring".

А если использовать такой алгоритм?

Пода1 берёт shared lock, делает select .. where status = NEW .. order by .. limit X

Потом для этих записей делает status = IN_PROGRESS, отпускает shared lock и идёт работать с этими записями.

Orange pi какая-нибудь маломощная не была бы надёжнее и удобнее? Вроде не особо дороже стоит, и на неё по ssh можно удаленно зайти.

p.s. я про ESP8266 вообще не в курсе, я джавист, мне надо много памяти кушац

Ага, можно. Проблема в том, что если у тебя сложный запрос, использующий несколько @Entity, то в чьем репозитории его хранить? Вторая проблема, если пихать "одноразовые" методы c @Query в репозиторий, то репозиторий пухнет. Если таких методов немного - @Query будет отличным вариантом.

  1. У вас был вариант писать в нужных местах native query через entity manager. Почему выбрали долгий путь и переписали весь проект на альтернативную технологию вместо этого варианта?

  2. У вас теперь нет из коробки фичей hibernate, таких как оптимистик лок, кеши, блокировки. Или есть? Не знаю как обстоят дела с транзакцией. Это всё надо теперь самим реализовывать?

  3. Уже потраченные силы и будущие затраты, плюс тот факт, что на проекте теперь не самый популярный рыночный стек. Не слишком ли много лишней работы? Поправьте если я не прав.

Прикольно, не знал что это прям паттерн. У нас в java в Spring Data JPA (самая популярная надстройка над ORM), функциональный интерфейс, который вызывается при формировании предиката, и имеющий and, or - так и называется: Specification.

А что за первоисточник? Черная книга по паттернам корпоративных приложений Фаулера?

На ревью приходится разгадывать кроссворды. Не делайте так, пожалуйста.

  1. Бороться с var бессмысленно. Это факт. Посмотри на количество своих минусов. Единственный способ - тимлид, который запретит использование.

  2. Подсказка в Intelij IDE поможет не сойти с ума. Однако на код ревью, будете и дальше гадать что там за тип.

  3. Если команда адекватная, постарайтесь договориться, о каком-нибудь умном использовании var. Например, только если есть справа new. Или в маленьком приватном методе. Потому что читать простыню кода в перемешку с var и без это гг.

  4. Дженерики, var с ними плохо работает, т.к. кастит к Object. Использование методов возвращающих T, все равно придется писать без var.

  5. var удобен, если тип часто меняется, например был Set, а стал List, не надо трогать тип ссылки.

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

Логично, что-то не подумал, спасибо, попробую.

При использовании SpringBootTest кешируется спринг контекст. Если сделать класс родитель тестов, прописать в нем эту аннотацию и все end to end тесты наследовать от родителя, то контекст будет построен один раз на все тесты. Но есть нюансы, легко сломать, была статья на этой неделе на Хабре.

https://habr.com/ru/companies/spring_aio/articles/905586/

Mockito unit test - это прекрасно, но если заинжектить что-то - пройдись по двадцати тестам, допиши что вернет мок, это бесит. Обычно переписываю mockito unit test на component test, если инжектов больше чем 3. Component test это имплементация родительского теста, с контекстом спринга, но без очистки бд.

Mockmvc и mockjpa ни разу не видел на живом проекте. Один раз попробовал, не удобно, component test наше всё.

Отличная статья. Жду полноценную статью от сообщества, как с этим бороться.

Вот несколько моих комментариев, как я работаю с тестами и моментов, которые я пока что не придумал как обойти:

0. По возможности пишем main классы таким образом, чтобы их можно было бы протестировать с помощью unit или @MockitoUnitTest (это те где @InjectMock, я вечно забываю как оно пишется, поэтому даже кастомную аннотацию завел).

1. Если ваш родительский класс с @SpringBootTest делает before и after, в которых полностью очищает таблицы бд, то можно завести наследника, например ComponentTest (как завещал Борисов), который не будет очищать таблицы (т.е. переопределить before и after родителя), но в котором будет полный контекст спринга. И использовать для компонентных тестов. Т.е. для тех тестов, где мокать было бы слишком много, но чистить бд не надо, либо вы сами в конце теста можете почистить только то, что необходимо.

2. @MockBean на все классы, которые ходят по ресту, в родительском классе. Будет удобно мокать результат, контекст спринга закешен.

3. @MockBean на все @Scheduler. Сами же методы шедулеров однострочные, делегируют работу в другой бин, который и тестируем. Контекст спринга закешен. Больше никаких левых select, когда на дебаге пытаешься найти место, откуда вылетает запрос.

4. Фича флаг, через application.property. В тесте рефлекшеном выставляю нужный параметр, в конце теста возвращаю старый. Контекст кешируется. Но такие тесты не переживут рефакторинг. Может есть лучше способ?

Моя боль:

5. @ConditionOnProperty и несколько имплементации бина, подкидываю имплементацию через аннотацию @TestPropertySource над тестом. Контекст не кешируется. Кто как с этим работает?

6. Не придумал пока что, что делать, когда реально нужен @MockBean. Очень жду советов в вашей статье. Пробовал в родительском классе делать @SpyBean, летели исключения, так времени и не было чтобы разобраться до конца. Пока что просто удаляю @MockBean из кода.

Интересно, спасибо за статью.

  1. Добавь, пожалуйста, сравнение по памяти.

  2. Всё-таки самое частое использование List - добавление в конец с последующей итерацией. И в таком кейсе использования ваша структура и LinkedList делают доп нагрузку на хип. К тому же ArrayList можно сразу задать нужного размера.

p.s. а ещё есть стримы)

На 20 метровую комнату - два ультразвуковых, с выхлопом 300 в час, с шумом около 30 дБ, без подсветки, с доливом воды сверху.

Практика. Оптимизировал тесты на одном из проектов.

Использование аннотации @MockBean в тестах, которые будут extends ваш родительский тест с @SpringBootTest, приводит к созданию нового спринг контекста. @SpyBean над бином в родительском тесте и Mockito.when() в дочернем - спринг контекст возьмётся из кеша. Если вы не хотите, чтобы тесты вашего проекта проходили час - надо постараться не плодить контексты спринга.

Спасибо за вопрос.


Я не пробовал, но судя по документации, для "входов" в приложение через @RestController - @RequestScope может прокатить.


Я использовал @RestController в статье для примера визуализации workflow.
На практике могут быть и другие "входы" в приложение, например @Scheduler или брокер сообщений, которые не проходят через сервлет, и соответственно @RequestScope не будет работать.

Спасибо, что делишься знаниями.

А если бы два метода, помеченные @Scheduled находились бы в разных классах, была бы проблема, что вторая джоба не стартует пока не выполнится первая? Обработчик шедулеров один на приложение или один на класс?

И ещё, если микросервисы + шедлок, то видимо проблема не так актуальна, поток из другой поды сервиса отработает.

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

Существует 2 очень похожих паттерна, которые в клиентском коде выглядят как вертикальная запись через точку: builder, fluent interface.

С практической точки зрения я бы классифицировал их следующим образом:

  1. Ленивость - действие выполняется в момент вызова промежуточного метода, или действие выполняется только в момент вызова терминальной операции.

  2. По типу возвращаемого значения. Возвращается тот же самый тип, или другой.

Представленный пример можно назвать ленивым спринговым билдером.

1

Information

Rating
5,467-th
Registered
Activity

Specialization

Backend Developer
Lead
Java