Привет!
Сегодня у меня день релизов!:)
Во-первых, я накатал обещанный микропрост про упражнения со Spring Boot Native.
А во-вторых и в главных - опубликовал первый том ретро реинжиниринга Проекта Э!
Ну и заодно немного обновил лендинг ЭП и добавил туда кейс Проекта Э
#case@ergonomic_code #project_e@ergonomic_code #posts@ergonomic_code
Сегодня у меня день релизов!:)
Во-первых, я накатал обещанный микропрост про упражнения со Spring Boot Native.
А во-вторых и в главных - опубликовал первый том ретро реинжиниринга Проекта Э!
Ну и заодно немного обновил лендинг ЭП и добавил туда кейс Проекта Э
#case@ergonomic_code #project_e@ergonomic_code #posts@ergonomic_code
👍6
Привет!
Опубликовал вторую менеджерско-организационную часть ретро Проэкта Э.
С описанием процесса работы, того что пошло не по плану, как факапились и чем всё закончилось
#posts@ergonomic_code #project_e@ergonomic_code
Опубликовал вторую менеджерско-организационную часть ретро Проэкта Э.
С описанием процесса работы, того что пошло не по плану, как факапились и чем всё закончилось
#posts@ergonomic_code #project_e@ergonomic_code
Алексей Жидков
Как я превратил легаси-проект в конфетку за полгода. Том 2 - Алексей Жидков
https://azhidkov.pro/
Привет!
Прочитал Software Architecture: The Hard Parts, более подходящим названием которой было бы "Yet another монолит в микросервисы - практическое пособие для мазохистов по выбору инструментов самоистязания".
Если серьёзно - единственное что мне в этой книге не понравилось - посыл, что микросервисы это стильно модно молодёжно, а монолит это устаревший подход. Я с этим посылом не согласен и придерживаюсь мнения, что в большей половине проектов с врождёнными болячками монолита будет жить проще, чем с врождёнными болячками микросервисов.
В остальном - очень качественный, полноценный и "comprehensive" материал, с обзором вариантов архитектур и адекватным обзором плюсов и минусов.
Так что рекомендую.
Особенно понравилось/зацепило глаз:
1. идея разделения на статическую и динамическую сцепленность. Думаю я себе это утащу в будущий пост про неё.
2. Идея пакетирования домен.поддомен.компонент и требование, чтобы компоненты были только в листах. У меня сейчас всё компоненты, при том допускаются вложенные компоненты и это не всегда работает. Не уверен, что утащу эту идею к себе, но точно подумаю в эту сторону
3. Они там так же как и я предлагаю технику выбора имени компонента, для определения его "разумности". И в целом в части декомпозиции, возможных вариантов решения сложных случаев и советов по выбору среди них - у нас совпадение процентов 80, но в книге материал больше проработан. Думаю, чем-то из книги смогу дополнить свой подход.
4. Понравилась идея семантической сцепленности - сцепленности в самой предметной области. Правда, эта штука ещё более расплывчатая, чем сцепленность в техническом решении.
4.1. Туда же хорошая идея, что техническое решение может только ухудшить (и часто так делает), семантическую сцепленность
4.2. Туда же идея, что при дизайне архитектор может "push back"-ать требования, если они содержать избыточную семантическую сцепленность, в лёгкой форме это у меня было в дизайне интеграции с ЕМИАС, где по изначальным требованиям казалось, что заказчик хочет семантической сцепленности регистрации пользователя в системе и привязке его к ЕМИАС
#books@ergonomic_code #project_e@ergonomic_code
Прочитал Software Architecture: The Hard Parts, более подходящим названием которой было бы "Yet another монолит в микросервисы - практическое пособие для мазохистов по выбору инструментов самоистязания".
Если серьёзно - единственное что мне в этой книге не понравилось - посыл, что микросервисы это стильно модно молодёжно, а монолит это устаревший подход. Я с этим посылом не согласен и придерживаюсь мнения, что в большей половине проектов с врождёнными болячками монолита будет жить проще, чем с врождёнными болячками микросервисов.
В остальном - очень качественный, полноценный и "comprehensive" материал, с обзором вариантов архитектур и адекватным обзором плюсов и минусов.
Так что рекомендую.
Особенно понравилось/зацепило глаз:
1. идея разделения на статическую и динамическую сцепленность. Думаю я себе это утащу в будущий пост про неё.
2. Идея пакетирования домен.поддомен.компонент и требование, чтобы компоненты были только в листах. У меня сейчас всё компоненты, при том допускаются вложенные компоненты и это не всегда работает. Не уверен, что утащу эту идею к себе, но точно подумаю в эту сторону
3. Они там так же как и я предлагаю технику выбора имени компонента, для определения его "разумности". И в целом в части декомпозиции, возможных вариантов решения сложных случаев и советов по выбору среди них - у нас совпадение процентов 80, но в книге материал больше проработан. Думаю, чем-то из книги смогу дополнить свой подход.
4. Понравилась идея семантической сцепленности - сцепленности в самой предметной области. Правда, эта штука ещё более расплывчатая, чем сцепленность в техническом решении.
4.1. Туда же хорошая идея, что техническое решение может только ухудшить (и часто так делает), семантическую сцепленность
4.2. Туда же идея, что при дизайне архитектор может "push back"-ать требования, если они содержать избыточную семантическую сцепленность, в лёгкой форме это у меня было в дизайне интеграции с ЕМИАС, где по изначальным требованиям казалось, что заказчик хочет семантической сцепленности регистрации пользователя в системе и привязке его к ЕМИАС
#books@ergonomic_code #project_e@ergonomic_code
O’Reilly Online Learning
Software Architecture: The Hard Parts
There are no easy decisions in software architecture. Instead, there are many hard parts--difficult problems or issues with no best practices--that force you to choose among various... - Selection from Software Architecture: The Hard Parts [Book]
👍5🔥1
Привет!
Собираю я вчера второй хот фикс на последний кровавый релиз Проекта Э с одной регрессией бэка и двумя костылями для багов в МП, пока шёл пайплайн заглянул на хабр, а там - Релиз без ошибок. Невозможное возможно?.
У мужика процесс намного более стандартизован (бюрократизирован?) и такого я себе пока позволить не могу, но в фокусе на функциональных тестах мы уже сходимся:)
С учётом того, что я заявляю, что ЭП позволяет существенно сократить кол-во багов, а в этом релизе на бэке нашли штук 5-6 багов (справедливости ради - только при тестировании МП и в течении 2-3 недель), то я этот релиз и все баги разберу по косточкам. И постараюсь опубликовать разбор, если удастся сохранить смысл, не нарушая NDA.
#posts@ergonomic_code #project_e@ergonomic_code
Собираю я вчера второй хот фикс на последний кровавый релиз Проекта Э с одной регрессией бэка и двумя костылями для багов в МП, пока шёл пайплайн заглянул на хабр, а там - Релиз без ошибок. Невозможное возможно?.
У мужика процесс намного более стандартизован (бюрократизирован?) и такого я себе пока позволить не могу, но в фокусе на функциональных тестах мы уже сходимся:)
С учётом того, что я заявляю, что ЭП позволяет существенно сократить кол-во багов, а в этом релизе на бэке нашли штук 5-6 багов (справедливости ради - только при тестировании МП и в течении 2-3 недель), то я этот релиз и все баги разберу по косточкам. И постараюсь опубликовать разбор, если удастся сохранить смысл, не нарушая NDA.
#posts@ergonomic_code #project_e@ergonomic_code
👍5
Привет!
Вспомнили свою профессию?:)
Если нет - возможно вам поможет гайдлайн разработки Проекта Э практически без купюр:)
Я его подготовил к публикации ещё в прошлом году, но собственно опубликовать дошли руки только сейчас.
#ergo_approach@ergonomic_code #project_e@ergonomic_code
Вспомнили свою профессию?:)
Если нет - возможно вам поможет гайдлайн разработки Проекта Э практически без купюр:)
Я его подготовил к публикации ещё в прошлом году, но собственно опубликовать дошли руки только сейчас.
#ergo_approach@ergonomic_code #project_e@ergonomic_code
👍6🔥4❤2
Привет!
Периодически гипотезы, лежащие в основе ЭП, рушатся о жестокую реальность промышленной разработки, что приводит к кризисам ЭП, которых уже было три штуки: раз по мотивам проекта Barcoder (решение), два (решение) и три (решение - нафик ООД, ДДД и private внутри одного репоза😀) - по мотивам #project_e.
И вот по мотивам #project_r за последние 5 дней у меня случился и благополучно разрешился очередной кризис ЭП:)
В связи с чем у меня пачка новостей.
Книга
Это уже новость второй свежести, но для контекста надо проговорить - я договорился с менеджером проектов издательства Питер начать с апреля плотную работу над книгой про ЭП. Так что надеюсь, на горизонте пары лет книга увидит свет.
Отказ от ФА
Номинально самая большая новость - я решил отказаться от ФА (которая когда-то была одним из трёх столпов ЭП).
Но по сути ничего не меняется - ЭП всё так же предполагает использование неизменяемых структур данных и максимально возможное разделение логики и ио.
Это просто признание реальности, что в ЭП, который начинался как сильно функциональный, я методично отказываюсь от отличительных черт ФА/ФП:
1. уже очень давно я отказался от монад и ROP-а в пользу защитных условий
2. затем я затащил операции в императивную оболочку
3. во многом по мотивам Проекта Р я вернул в милость выброс исключений вместо возвращения Result
4. по мотивам Проекта Р, я утащил сбалансированную форму системы с архитектурного уровня системы, на локальный уровень отдельных методов
Отказ от SDJ как дефолтной технологии работы с БД
А вот по сути самое больше изменение - я решил отказаться от SDJ в качестве дефолта для работы с БД.
Это всё ёще допустимый в рамках ЭП т.к. его всё ещё легче "продать" заказчикам и коллегам, но по умолчанию я теперь предлагаю использовать какой-то легковесный DSL - jooq или Exposed, ещё не решил что именно.
Это опять же обусловлено опытом Проекта Р - там у меня львиная доля запросов чтения рукописные, потому что SDJ не в состоянии эффективно доставать данные этого проекта, а после того, как мне пришлось ещё и два кастомных метода сохранения написать - стало понятно, что я борюсь с технологией. Этому решению так же поспособствовали пост из канала одного из участников нашей группы.
И решение перейти на UUID-ы, которое так же было обусловлено опытом разработки Проекта Р, где надо сетапать огромные графы объектов в тестах и с генераций ИДов на уровне БД это очень сложно.
Новая версия описания Эргономичной архитектуры
На мой взгляд самая крутая новость - я выложил новый подход к описанию ЭА.
По сути там ничего не изменилось, изменилась только подача.
Но эта новая подача мне настолько нравится, что я решил показать самый первый черновик.
Основная фишка - я отказался от попытки быть как все и уместить архитектуру на одну картинку и ввёл идею проекций. Их три:
1. проекция структуры данных (модель данных) - тут про агрегаты и связи между ними
2. проекция состояния (объектная модель) - тут про объекты в рантайме (порты, операции, ресурсы) и связи между ними
3. проекция структуры поведения (процедурная модель) - тут про методы и связи между ними
Плюс я туда сразу накидал кучу примеров (пока на словах😕), а так же процессы построения всех этих структур и итоговой архитектуры.
Над единой картинкой я тоже ещё подумаю: кажется, судя по проектам физических изделий, где есть проекции по плоскостям плюс изометрия или проекты зданий, где есть тоже должны быть разные проекции и разные слои (с электропроводкой, например) - для ЭА тоже можно что-то такое сделать.
И возвращаясь к книге - эта статья по сути - четверть книги. Заполнить там пробелы, добавить примеры и теоретическая часть по ЭА готова. Вспоминая про бейзкамповский Hill Chart, у меня сейчас такое ощущение, что я достиг холма реализации ЭА и дальше только дело техники. Лишь бы очередной проект не зафейлил очередную гипотезу😄
#the_book@ergonomic_code #functional_architecture@ergonomic_code #ergo_arch@ergonomic_code #ergo_persistance@ergonomic_code #spring_data_jdbc@ergonomic_code
Периодически гипотезы, лежащие в основе ЭП, рушатся о жестокую реальность промышленной разработки, что приводит к кризисам ЭП, которых уже было три штуки: раз по мотивам проекта Barcoder (решение), два (решение) и три (решение - нафик ООД, ДДД и private внутри одного репоза😀) - по мотивам #project_e.
И вот по мотивам #project_r за последние 5 дней у меня случился и благополучно разрешился очередной кризис ЭП:)
В связи с чем у меня пачка новостей.
Книга
Это уже новость второй свежести, но для контекста надо проговорить - я договорился с менеджером проектов издательства Питер начать с апреля плотную работу над книгой про ЭП. Так что надеюсь, на горизонте пары лет книга увидит свет.
Отказ от ФА
Номинально самая большая новость - я решил отказаться от ФА (которая когда-то была одним из трёх столпов ЭП).
Но по сути ничего не меняется - ЭП всё так же предполагает использование неизменяемых структур данных и максимально возможное разделение логики и ио.
Это просто признание реальности, что в ЭП, который начинался как сильно функциональный, я методично отказываюсь от отличительных черт ФА/ФП:
1. уже очень давно я отказался от монад и ROP-а в пользу защитных условий
2. затем я затащил операции в императивную оболочку
3. во многом по мотивам Проекта Р я вернул в милость выброс исключений вместо возвращения Result
4. по мотивам Проекта Р, я утащил сбалансированную форму системы с архитектурного уровня системы, на локальный уровень отдельных методов
Отказ от SDJ как дефолтной технологии работы с БД
А вот по сути самое больше изменение - я решил отказаться от SDJ в качестве дефолта для работы с БД.
Это всё ёще допустимый в рамках ЭП т.к. его всё ещё легче "продать" заказчикам и коллегам, но по умолчанию я теперь предлагаю использовать какой-то легковесный DSL - jooq или Exposed, ещё не решил что именно.
Это опять же обусловлено опытом Проекта Р - там у меня львиная доля запросов чтения рукописные, потому что SDJ не в состоянии эффективно доставать данные этого проекта, а после того, как мне пришлось ещё и два кастомных метода сохранения написать - стало понятно, что я борюсь с технологией. Этому решению так же поспособствовали пост из канала одного из участников нашей группы.
И решение перейти на UUID-ы, которое так же было обусловлено опытом разработки Проекта Р, где надо сетапать огромные графы объектов в тестах и с генераций ИДов на уровне БД это очень сложно.
Новая версия описания Эргономичной архитектуры
На мой взгляд самая крутая новость - я выложил новый подход к описанию ЭА.
По сути там ничего не изменилось, изменилась только подача.
Но эта новая подача мне настолько нравится, что я решил показать самый первый черновик.
Основная фишка - я отказался от попытки быть как все и уместить архитектуру на одну картинку и ввёл идею проекций. Их три:
1. проекция структуры данных (модель данных) - тут про агрегаты и связи между ними
2. проекция состояния (объектная модель) - тут про объекты в рантайме (порты, операции, ресурсы) и связи между ними
3. проекция структуры поведения (процедурная модель) - тут про методы и связи между ними
Плюс я туда сразу накидал кучу примеров (пока на словах😕), а так же процессы построения всех этих структур и итоговой архитектуры.
Над единой картинкой я тоже ещё подумаю: кажется, судя по проектам физических изделий, где есть проекции по плоскостям плюс изометрия или проекты зданий, где есть тоже должны быть разные проекции и разные слои (с электропроводкой, например) - для ЭА тоже можно что-то такое сделать.
И возвращаясь к книге - эта статья по сути - четверть книги. Заполнить там пробелы, добавить примеры и теоретическая часть по ЭА готова. Вспоминая про бейзкамповский Hill Chart, у меня сейчас такое ощущение, что я достиг холма реализации ЭА и дальше только дело техники. Лишь бы очередной проект не зафейлил очередную гипотезу
#the_book@ergonomic_code #functional_architecture@ergonomic_code #ergo_arch@ergonomic_code #ergo_persistance@ergonomic_code #spring_data_jdbc@ergonomic_code
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥6👍4❤2
Эргономичный код
Привет! С подачи Романа Русакова запоем прочитал The API. Очень крутая книга, рекомендую. Роман - спасибо:) Так же вы, возможно, задаётесь вопросом что это я затих. Вряд ли, конечно, но я всё равно отвечу - лопачу джиру Проект Э:) Чтобы понять стоило ли…
Привет!
Я тут недавно прочитал Overengineering in Onion/Hexagonal Architectures (перевод).
В целом с посылом поста я согласен (кроме мёржа REST-аннотаций в сервисы, хотя сам об этом думал), но там ничего суперкрутого - этот мой пост не про тот пост:)
А про собственную...Глу... человечность, назовём это так:)
В посте по ссылке есть тезис:
Но я в 22-ом году (на 18-ом году коммерческой практики и примерно 5-ом году знания про Чистую архитектуру, ДДД, оркестрацию и сервисы приложений) всё равно изобрёл объектно-ориентированную декомпозицию. И пошёл делать по ней #project_e. И получил ровно, то, чего позволяют избегать сервисы приложений - высокую связанность между модулями-объектами.
Сколько ещё у меня таких "изобретений" из-за того что "смотрю в книгу, вижу фигу"? Вопрос риторический, конечно. Время покажет, всё что покажет - расскажу как на духу. Сегодня начал писать пост с ретро #project_r
PS>
И в топик "простых" CRUD приложений из комментов ко вчерашнему посту: в Overengineering in Onion/Hexagonal Architectures про них тоже тоже есть:
#posts@ergonomic_code #ergo_arch@ergonomic_code #ergo_approach@ergonomic_code
Я тут недавно прочитал Overengineering in Onion/Hexagonal Architectures (перевод).
В целом с посылом поста я согласен (кроме мёржа REST-аннотаций в сервисы, хотя сам об этом думал), но там ничего суперкрутого - этот мой пост не про тот пост:)
А про собственную...
В посте по ссылке есть тезис:
To put it another way, it is a design goal of the Application Service to host orchestration logic to allow lower-level components to become less coupled to one another.
—
Другими словами, Application Services предназначены для размещения логики оркестрации, что позволяет компонентам более низкого уровня быть менее связанными друг с другом.
Но я в 22-ом году (на 18-ом году коммерческой практики и примерно 5-ом году знания про Чистую архитектуру, ДДД, оркестрацию и сервисы приложений) всё равно изобрёл объектно-ориентированную декомпозицию. И пошёл делать по ней #project_e. И получил ровно, то, чего позволяют избегать сервисы приложений - высокую связанность между модулями-объектами.
Сколько ещё у меня таких "изобретений" из-за того что "смотрю в книгу, вижу фигу"? Вопрос риторический, конечно. Время покажет, всё что покажет - расскажу как на духу. Сегодня начал писать пост с ретро #project_r
PS>
И в топик "простых" CRUD приложений из комментов ко вчерашнему посту: в Overengineering in Onion/Hexagonal Architectures про них тоже тоже есть:
Like any tool, concentric architectures are not suitable for any software project. If the domain complexity of your problem is fairly low (CRUD-like), or if the challenge of your application is NOT in the complexity of its business rules, then the Onion/Hexagonal/Ports-Adapters/Clean Architecture might not be the best choice, and you might be better off with vertical slicing, anemic model, CQRS, or another type of architecture.
—
Как и любой другой инструмент, концентрическая архитектура подходит не для всех проектов. Если сложность предметной области вашей задачи довольно низкая (CRUDо-подобная) или если сложность вашего приложения заключается не в сложности его бизнес-правил, то архитектура Onion/Hexagonal/Ports-Adapters/Clean может оказаться не лучшим выбором, и вам, возможно, лучше использовать вертикальную архитектуру, анемичную модель, CQRS или другой тип архитектуры.
#posts@ergonomic_code #ergo_arch@ergonomic_code #ergo_approach@ergonomic_code
Victor Rentea
Overengineering in Onion/Hexagonal Architectures
Clean Architecture, Onion Architecture, and Hexagonal Architecture (aka Ports-and-Adapters) have become the norm for backend system design today. Powerful influencers have promoted these architectures without stressing enough that they are (overly)complex…
❤6
Привет!
Третья большая новость наконец дозрела - я утряс все формальности и возобновил работу над Проектом Э!
Пока я пилил #project_r@ergonomic_code, заказчик пилил новый девайс, который делает замеры постоянно. И после его внедрения, нагрузка поднимется с ~3 измерений на пользователя в день до ~700.
А в самом оптимистичном сценарии - дорастёт до 50 RPS. Это ещё не хайлоад, конечно, но уже достаточно серьёзная нагрузка, которая не простит откровенно неэффективных решений.
Соответственно, сейчас моя основная задача немного допилить бэк для поддержки нового устройства и подготовить его к росту нагрузки. Плюс в бэклоге накопилась пачка фич, которые тоже надо будет сделать.
И на мой взгляд, это очень крутая новость для ЭП. Это значит, что у меня будет реальная обратная связь из первых рук о том, как ЭП масштабируется и по размеру проекта (сейчас - 40k строк Котлин-кода и 72 таблицы) и по RPS.
Кроме того, у меня был очень любопытный опыт приёма на поддержку собственного проекта после практически 1.5-летнего перерыва. Там, на самом деле есть прям много чего написать, но, к сожалению, не осилю. Если в целом общие ощущения - нот бэд, но за почти три года с момента начала разработки Проекта Э, Эргономичный подход сделал огромный шаг вперёд, особенно в части тестирования.
Плюс чуть подробнее поделюсь ещё одним инсайтом: идея, что можно в одном модуле попилить проект на вертикальные слайсы в пакетах и покрыть отсутствие циклических зависимостей между ними ArchUnit-тестом, для того чтобы вертикальные кусочки можно было легко вынести - оказалась тупиковой. В моей реализации, по крайней мере.
Во-первых, за 1.5 года в продовый код пробралось несколько циклов. И это при том, что я часа 4 потратил на то, чтобы написать максимально строгий Арч-юнит тест. Но это была меньшая из проблем - их я разорвал за несколько часов.
Потому что во-вторых - в тестах произошла тотальная катастрофа. Там образовался дикий клубок зависимостей, который я распутывал и распиливал неделю. Наверное, тесты надо покрывать ArchUnit-тестами тоже:)
В общем если вы делаете модульный монолит, и хотите иметь возможность быстро выносить модули в отдельные сервисы - не лениесь как я и заводите для них сразу отдельные модули
#project_e@ergonomic_code #ergo_approach@ergonomic_code
Третья большая новость наконец дозрела - я утряс все формальности и возобновил работу над Проектом Э!
Пока я пилил #project_r@ergonomic_code, заказчик пилил новый девайс, который делает замеры постоянно. И после его внедрения, нагрузка поднимется с ~3 измерений на пользователя в день до ~700.
А в самом оптимистичном сценарии - дорастёт до 50 RPS. Это ещё не хайлоад, конечно, но уже достаточно серьёзная нагрузка, которая не простит откровенно неэффективных решений.
Соответственно, сейчас моя основная задача немного допилить бэк для поддержки нового устройства и подготовить его к росту нагрузки. Плюс в бэклоге накопилась пачка фич, которые тоже надо будет сделать.
И на мой взгляд, это очень крутая новость для ЭП. Это значит, что у меня будет реальная обратная связь из первых рук о том, как ЭП масштабируется и по размеру проекта (сейчас - 40k строк Котлин-кода и 72 таблицы) и по RPS.
Кроме того, у меня был очень любопытный опыт приёма на поддержку собственного проекта после практически 1.5-летнего перерыва. Там, на самом деле есть прям много чего написать, но, к сожалению, не осилю. Если в целом общие ощущения - нот бэд, но за почти три года с момента начала разработки Проекта Э, Эргономичный подход сделал огромный шаг вперёд, особенно в части тестирования.
Плюс чуть подробнее поделюсь ещё одним инсайтом: идея, что можно в одном модуле попилить проект на вертикальные слайсы в пакетах и покрыть отсутствие циклических зависимостей между ними ArchUnit-тестом, для того чтобы вертикальные кусочки можно было легко вынести - оказалась тупиковой. В моей реализации, по крайней мере.
Во-первых, за 1.5 года в продовый код пробралось несколько циклов. И это при том, что я часа 4 потратил на то, чтобы написать максимально строгий Арч-юнит тест. Но это была меньшая из проблем - их я разорвал за несколько часов.
Потому что во-вторых - в тестах произошла тотальная катастрофа. Там образовался дикий клубок зависимостей, который я распутывал и распиливал неделю. Наверное, тесты надо покрывать ArchUnit-тестами тоже:)
В общем если вы делаете модульный монолит, и хотите иметь возможность быстро выносить модули в отдельные сервисы - не лениесь как я и заводите для них сразу отдельные модули
#project_e@ergonomic_code #ergo_approach@ergonomic_code
Алексей Жидков
Как я превратил легаси-проект в конфетку за полгода. Том 1 - Алексей Жидков
https://azhidkov.pro/
🔥2
Вы, полагаю, уже устали от этих постов. Но мясного материала пока нет - он весь варится.
А варится у меня следующее:
1. Я в #project_e собираюсь пилить новый небольший сервис на пару ресурсов и там хочу поставить пару экспериментов.
1.1 Во-первых, сделать пару прототипов на Spring MVC + Data JDBC и http4k + jooq и посмотреть какая будет разница по потреблению ресурсов (памяти в первую очередь). Об этом я точно напишу как минимум микропост. А если http4k/jooq уместятся хотя бы в половину памяти Спринга - скорее всего возьму их в прод и тогда там будет много инсайтов о жизни вне Спринга:)
1.2. Там же хочу поставить другой эксперимент - генерировать хттп-клиенты для тестов по Open API спеке. Надеюсь, что это мне даст:
1.2.1 Чистый код контроллеров и АПИ не ограниченные поддерживаемыми возможности генераторов по коду
1.2.2 Спеку отделённую от кода, так что её сможет саппортить аналитик
1.2.3 Гарантию актуальности спеки (за счёт контроля при сборке 100% покрытия кода контроллеров тестами)
1.2.4 Отсутствие кодогенерации кода контроллеров
2. В рамках пиара исследования, я собираюсь написать пару постов
2.1 Действительно ли SOLID повышает поддерживаемость? - по науке проанализировать имеющиеся анкеты на предмет того есть ли статестически достоверная (по ослабленному критерию достоверности) корреляция между применением принципов SOLID и оценкой проекта как поддерживаемого
2.2 Эргономичная архитектура тестов - актуализировать и нормально оформить старый микропост о том, как у меня устроены тесты
В общем, стей тюнед, будет интересно:)
А варится у меня следующее:
1. Я в #project_e собираюсь пилить новый небольший сервис на пару ресурсов и там хочу поставить пару экспериментов.
1.1 Во-первых, сделать пару прототипов на Spring MVC + Data JDBC и http4k + jooq и посмотреть какая будет разница по потреблению ресурсов (памяти в первую очередь). Об этом я точно напишу как минимум микропост. А если http4k/jooq уместятся хотя бы в половину памяти Спринга - скорее всего возьму их в прод и тогда там будет много инсайтов о жизни вне Спринга:)
1.2. Там же хочу поставить другой эксперимент - генерировать хттп-клиенты для тестов по Open API спеке. Надеюсь, что это мне даст:
1.2.1 Чистый код контроллеров и АПИ не ограниченные поддерживаемыми возможности генераторов по коду
1.2.2 Спеку отделённую от кода, так что её сможет саппортить аналитик
1.2.3 Гарантию актуальности спеки (за счёт контроля при сборке 100% покрытия кода контроллеров тестами)
1.2.4 Отсутствие кодогенерации кода контроллеров
2. В рамках пиара исследования, я собираюсь написать пару постов
2.1 Действительно ли SOLID повышает поддерживаемость? - по науке проанализировать имеющиеся анкеты на предмет того есть ли статестически достоверная (по ослабленному критерию достоверности) корреляция между применением принципов SOLID и оценкой проекта как поддерживаемого
2.2 Эргономичная архитектура тестов - актуализировать и нормально оформить старый микропост о том, как у меня устроены тесты
В общем, стей тюнед, будет интересно:)
Алексей Жидков
Тестирование Trainer Advisor: теория - Алексей Жидков
https://azhidkov.pro/
❤7👍5
Привет!
У меня на этой недели был леденящий душу опыт с хэппи эндом.
Я всю неделю активно девелопал новый сервис в Проекте Э и при этом активно экспериментировал с оптимизацией потребления РАМ и временем старта тестов.
И делал всё это вместе GPT-5 low reasoning через бесплатный план Windsurfa-а.
И он реально хорош. Он на порядок-два лучше GPT-4 и Sonnet-4. Практически не глючит и в 9 из 10 случаев быстрее меня решает WTF-ы со Спрингом. Например, у меня был value object в Sdj-модели с кастомным конвертером. И SDJ не мог найти конвертер. Я по привычке залез в кишки спринга и увидел, что конвертер доступен. Но не работает. Тут меня чёрт дёрнул спросить у гопатыча и он через минуту-две сказал, что я лупень и в модели импортнул не тот класс - у меня после экспериментов остался второй такой же класс в другом пакете. Мой опыт показывает, что я на такой фигне мог залипнуть на пару часов.
При решении другой проблемы, он в рассуждениях пошёл гуглить исходники спринга, нагуглил и выдал корректное решение.
Короче я напрягся и начал думать, что лавочку с ЭП пора прикрывать, потому как к тому времени когда я его закончу код будут писать только нейронки.
Однако сегодня я смог таки победить бездушную машину. В WTF-е с kover-ом. У меня была проблема с тем что конфиг на Kotlin DSL не компилялся. Тут я уже наоборот сходу пошёл к гопатычу и он начал глючить как не в себя. И не решил проблему. Тогда я сам вдумчиво прочитал сообщение об ошибке и решил проблему за минуту.
Плюс девелопать вайб-кодингом я с ним тоже попробовал. Вот это уже не особо понравилось. Код он генеряет в целом рабочий и сносный. Но делает это долго и хз чем самому в этот момент заниматься - на другую задачу не переключишься, т.к. за гопатычем следить надо на предмет хотя бы завершения. Ток котиков можно смотреть в этот момент.
Плюс код после него всё равно надо тщательно ревьювить и дорабатывать если не напильником, то мелкой наждачкой.
В общем у меня ощущение, что руками с автодополнением было бы точно не медленнее работать.
Но думать в направлении адаптации ЭП под нейронки - всё равно буду:) Соображения на этот счёт есть, но в другой раз напишу:)
В общем:
1. Для популярных фреймворков GPT 5 - нереально крут. Срочно пробуйте если ещё нет.
2. Но он всё ещё СЛАУ-переросток, не одупляет что он делает и в нестандартных случаях всё ещё бесполезен
#ai@ergonomic_code #project_e@ergonomic_code
У меня на этой недели был леденящий душу опыт с хэппи эндом.
Я всю неделю активно девелопал новый сервис в Проекте Э и при этом активно экспериментировал с оптимизацией потребления РАМ и временем старта тестов.
И делал всё это вместе GPT-5 low reasoning через бесплатный план Windsurfa-а.
И он реально хорош. Он на порядок-два лучше GPT-4 и Sonnet-4. Практически не глючит и в 9 из 10 случаев быстрее меня решает WTF-ы со Спрингом. Например, у меня был value object в Sdj-модели с кастомным конвертером. И SDJ не мог найти конвертер. Я по привычке залез в кишки спринга и увидел, что конвертер доступен. Но не работает. Тут меня чёрт дёрнул спросить у гопатыча и он через минуту-две сказал, что я лупень и в модели импортнул не тот класс - у меня после экспериментов остался второй такой же класс в другом пакете. Мой опыт показывает, что я на такой фигне мог залипнуть на пару часов.
При решении другой проблемы, он в рассуждениях пошёл гуглить исходники спринга, нагуглил и выдал корректное решение.
Короче я напрягся и начал думать, что лавочку с ЭП пора прикрывать, потому как к тому времени когда я его закончу код будут писать только нейронки.
Однако сегодня я смог таки победить бездушную машину. В WTF-е с kover-ом. У меня была проблема с тем что конфиг на Kotlin DSL не компилялся. Тут я уже наоборот сходу пошёл к гопатычу и он начал глючить как не в себя. И не решил проблему. Тогда я сам вдумчиво прочитал сообщение об ошибке и решил проблему за минуту.
Плюс девелопать вайб-кодингом я с ним тоже попробовал. Вот это уже не особо понравилось. Код он генеряет в целом рабочий и сносный. Но делает это долго и хз чем самому в этот момент заниматься - на другую задачу не переключишься, т.к. за гопатычем следить надо на предмет хотя бы завершения. Ток котиков можно смотреть в этот момент.
Плюс код после него всё равно надо тщательно ревьювить и дорабатывать если не напильником, то мелкой наждачкой.
В общем у меня ощущение, что руками с автодополнением было бы точно не медленнее работать.
Но думать в направлении адаптации ЭП под нейронки - всё равно буду:) Соображения на этот счёт есть, но в другой раз напишу:)
В общем:
1. Для популярных фреймворков GPT 5 - нереально крут. Срочно пробуйте если ещё нет.
2. Но он всё ещё СЛАУ-переросток, не одупляет что он делает и в нестандартных случаях всё ещё бесполезен
#ai@ergonomic_code #project_e@ergonomic_code
👍10❤4
Привет!
У меня в новом сервисе в Проекте Э на Spring Boot 3.5 новый рекорд скорости тестов:)
54 кейса за 2.7 секунды, 90% тестов - < 60мс, медиана - 14мс.
Сетап:
1. инфра (PostgreSQL и Minio на RAM-диске) запускается руками по кнопке в Идее docker compose-ом.
2. Отказ от компонент скана бинов
3. Отказ от скана авто-конфигов
4. ленивая иницилазиация бинов (spring.main.lazy-initialization)
5. Работа через WebTestClient с MockMvc
Не 5мс на кейс, как у Саши Раковского, конечно, но уже близко и это полный набор тестов, после которого можно деплоить в прод:)
#ergo_testing@ergonomic_code #project_e@ergonomic_code #spring_boot@ergonomic_code
У меня в новом сервисе в Проекте Э на Spring Boot 3.5 новый рекорд скорости тестов:)
54 кейса за 2.7 секунды, 90% тестов - < 60мс, медиана - 14мс.
Сетап:
1. инфра (PostgreSQL и Minio на RAM-диске) запускается руками по кнопке в Идее docker compose-ом.
2. Отказ от компонент скана бинов
3. Отказ от скана авто-конфигов
4. ленивая иницилазиация бинов (spring.main.lazy-initialization)
5. Работа через WebTestClient с MockMvc
Не 5мс на кейс, как у Саши Раковского, конечно, но уже близко и это полный набор тестов, после которого можно деплоить в прод:)
#ergo_testing@ergonomic_code #project_e@ergonomic_code #spring_boot@ergonomic_code
🔥8👍7
Привет!
Обещанный микропост про эксперимент с http4k.
Напомню контекст - мне недавно понадобилось сделать в Проекте Э новый небольшой сервис и у нас довольно сильно ограничена RAM на стендах, поэтому я решил поэксперементировать с http4k +jooq jdbi с целью сократить потреблением RAM.
Изначально я написал прототип на Spring Boot 3.5 (MVC + Data JDBC) буквально с парой методов - создание сущности на 3 поля плюс файла (в минио) и получение файла.
Далее методика всех измерений была следующая:
1. запустить сервис
2. curl-запросами создать сущность и получить картинку
3. померить ps-ом RSS процесса.
И для чистого Spring Boot я получил 270mb.
Тогда я написал прототип на http4k + jdbi и для него получил 236mb. В целом на этом можно было бы и закончить эксперимент, т.к. экономия была несущественная, зато с http4k пришлось бы руками писать аутентификацию, rbac, управление транзакциями, кэширование, да ещё и запросы на доменные модели руками мапить.
Но я не закончил и накопал ещё пару любопытных штук.
Первым делом я пошёл к гопатычу и спросил какой стэк под JVM дал бы большую экономию по памяти. Он накидал несколько вариантов, среди которых обещал ~150mb RAM для Micronaut. Я спросил за счёт чего Micronaut экономит память. Он сказал - за счёт Netty.
Я думаю ну ладно, в http4k переехать на Netty - дело пары строк.
И переехал. И получил 156mb RAM.
А заодно ещё и дикий WTF - у http4k API обработчиков запросов - синхронное. И нет ручки, чтобы настроить Netty на виртуальные потоки. То есть из коробки Netty в http4k - это фикция.
Пока разбирался как таки примострячить виртуальные потоки в http4k/Netty залез в исходники и нашёл там коммент с "элегантым" решением этой проблемы:
Ну т.е. хотите чтобы Нетти норм работал - копипастьте код либы и делайте с ним что хотите🤦♂️ О каких 99% юзкейсах они говорят - вообще не представляю.
В общем поматерился я на хттп4к и подумал, что Spring Boot же тоже может в Netty. И там вроде как даже не обязательно делать контроллеры на Reactor-е или корутинах - вроде как можно писать обычные контроллеры и настроить (вот это ничего себе!) тредпул на котором Спринг будет их дёргать.
Сказано-сделано, минут за 15-30 переехал на WebFlux, барабанная дробь... 245mb... Тут у меня бюджет на эксперименты начал уже заканчиваться, поэтому я решил, что дело количества зависимостей, которые тащит с собой WebFlux и пошёл дальше.
А дальше я решил дать ещё один шанс Spring Boot Native. Как и в прошлый раз пришлось повоевать с рефлекшеном, но на этот раз со мной был GPT-5 и эти проблемы он щёлкал на раз-два, поэтому ещё минут через 30 я получил цифры для нативной сборки - 157mb. Неплохо.
Однако пока копался с Нативом, я наткнулся на Spring Boot Ahead-of-Time Processing, который должен был дать оптимизацию времени запуска и потребления RAM без 3 минут компиляции и сюрпризов в рантайме Нативной сборки. И он в целом дал - 234mb RAM.
Итого вышли такие цифры:
1. Spring Boot + Tomcat - 270mb
2. http4k + Jetty - 236mb
3. http4k + Netty - 156mb
4. Spring Boot + Netty - 245mb
3. Spring Boot Native + Tomcat - 157mb
4. Spring Boot AOT Processing + Tomcat - 234mb
Помедитировав на них я решил, что переход на http4k того не стоит и снова остался на Spring Boot. Не люблю его за монструозность и количество автомагии но для меня сейчас он всё ещё остаётся наименьшим из зол.
#spring_boot@ergonomic_code #project_e@ergonomic_code
Обещанный микропост про эксперимент с http4k.
Напомню контекст - мне недавно понадобилось сделать в Проекте Э новый небольшой сервис и у нас довольно сильно ограничена RAM на стендах, поэтому я решил поэксперементировать с http4k +
Изначально я написал прототип на Spring Boot 3.5 (MVC + Data JDBC) буквально с парой методов - создание сущности на 3 поля плюс файла (в минио) и получение файла.
Далее методика всех измерений была следующая:
1. запустить сервис
2. curl-запросами создать сущность и получить картинку
3. померить ps-ом RSS процесса.
И для чистого Spring Boot я получил 270mb.
Тогда я написал прототип на http4k + jdbi и для него получил 236mb. В целом на этом можно было бы и закончить эксперимент, т.к. экономия была несущественная, зато с http4k пришлось бы руками писать аутентификацию, rbac, управление транзакциями, кэширование, да ещё и запросы на доменные модели руками мапить.
Но я не закончил и накопал ещё пару любопытных штук.
Первым делом я пошёл к гопатычу и спросил какой стэк под JVM дал бы большую экономию по памяти. Он накидал несколько вариантов, среди которых обещал ~150mb RAM для Micronaut. Я спросил за счёт чего Micronaut экономит память. Он сказал - за счёт Netty.
Я думаю ну ладно, в http4k переехать на Netty - дело пары строк.
И переехал. И получил 156mb RAM.
А заодно ещё и дикий WTF - у http4k API обработчиков запросов - синхронное. И нет ручки, чтобы настроить Netty на виртуальные потоки. То есть из коробки Netty в http4k - это фикция.
Пока разбирался как таки примострячить виртуальные потоки в http4k/Netty залез в исходники и нашёл там коммент с "элегантым" решением этой проблемы:
Stock version of an Netty Server. Not that if you want to configure your own server instance you
can duplicate this code and modify it as required. We are purposefully trying to limit options
here to keep the API simple for the 99% of use-cases.
Ну т.е. хотите чтобы Нетти норм работал - копипастьте код либы и делайте с ним что хотите
В общем поматерился я на хттп4к и подумал, что Spring Boot же тоже может в Netty. И там вроде как даже не обязательно делать контроллеры на Reactor-е или корутинах - вроде как можно писать обычные контроллеры и настроить (вот это ничего себе!) тредпул на котором Спринг будет их дёргать.
Сказано-сделано, минут за 15-30 переехал на WebFlux, барабанная дробь... 245mb... Тут у меня бюджет на эксперименты начал уже заканчиваться, поэтому я решил, что дело количества зависимостей, которые тащит с собой WebFlux и пошёл дальше.
А дальше я решил дать ещё один шанс Spring Boot Native. Как и в прошлый раз пришлось повоевать с рефлекшеном, но на этот раз со мной был GPT-5 и эти проблемы он щёлкал на раз-два, поэтому ещё минут через 30 я получил цифры для нативной сборки - 157mb. Неплохо.
Однако пока копался с Нативом, я наткнулся на Spring Boot Ahead-of-Time Processing, который должен был дать оптимизацию времени запуска и потребления RAM без 3 минут компиляции и сюрпризов в рантайме Нативной сборки. И он в целом дал - 234mb RAM.
Итого вышли такие цифры:
1. Spring Boot + Tomcat - 270mb
2. http4k + Jetty - 236mb
3. http4k + Netty - 156mb
4. Spring Boot + Netty - 245mb
3. Spring Boot Native + Tomcat - 157mb
4. Spring Boot AOT Processing + Tomcat - 234mb
Помедитировав на них я решил, что переход на http4k того не стоит и снова остался на Spring Boot. Не люблю его за монструозность и количество автомагии но для меня сейчас он всё ещё остаётся наименьшим из зол.
#spring_boot@ergonomic_code #project_e@ergonomic_code
Please open Telegram to view this post
VIEW IN TELEGRAM
👏8👍6🔥5❤3
Привет!
Поучительная история о важности именования.
У меня тут джуны недавно в Проекте Э запилили пуши.
И пока ревьювил бэк я там наткнулся на строчку с дип линкой (в которых я не шарю) "myapp://<some-screen>", которая отправляется в МП.
И она мне сразу не понравилась из-за myapp. Фик знает почему myapp - плохо.
Попахивает дилетантством, небрежностью и копипастой со стековерфлоу.
И вроде как непонятно что она значит. Ну т.е. понятно, конечно - моё приложение. Но кто это писал? Чьё это приложение?
И тут вроде тоже, и мне, и любому читателю этого кода с вероятностью 99% будет очевидно, кто это писал и чьё это приложение.
Но всё равно с этим именем "что-то не то".
В общем я был уверен, что это имя херовое, но сам убедительных (для себя) аргументов не придумал и пошёл гуглить рекомендации по формированию диплинок.
И нагуглил, что кастомные схемы в диплинках - это дыра в безопасности в виде Deep Link Collision.
Из-за неё кто угодно может подписаться на наши диплинки. На андроиде в этом случае откроется диалог с вопросом в какое приложение перейти - наше или чужое (как вариант - с таким же именем и иконкой), а на иосе - вообще "If multiple apps register the same scheme, the app the system targets is undefined" 🤯
И это далеко не первый раз когда я на ревью начинаю докапываться до имени, а в итоге выхожу на серьёзный баг или проблему в архитектуре или просто нахожу лучшее решение, сформулированное в корректных терминах.
В общем мой совет: внимательно следите за именами в коде, кривые имена очень часто свидетельствуют о кривом коде.
На самом деле я считаю, что вопреки расхожему мнению, для разработчика [бакенда [информационных систем]] важнее умение хорошо писать на русском, чем "знать математику". Так что заводите свои блоги и каналы, чтобы практиковаться в письме и не делегируйте письмо ЛЛМкам:)
Если заведёте - пишите, напишу об этом в этом канале :)
#project_e@ergonomic_code
Поучительная история о важности именования.
У меня тут джуны недавно в Проекте Э запилили пуши.
И пока ревьювил бэк я там наткнулся на строчку с дип линкой (в которых я не шарю) "myapp://<some-screen>", которая отправляется в МП.
И она мне сразу не понравилась из-за myapp. Фик знает почему myapp - плохо.
Попахивает дилетантством, небрежностью и копипастой со стековерфлоу.
И вроде как непонятно что она значит. Ну т.е. понятно, конечно - моё приложение. Но кто это писал? Чьё это приложение?
И тут вроде тоже, и мне, и любому читателю этого кода с вероятностью 99% будет очевидно, кто это писал и чьё это приложение.
Но всё равно с этим именем "что-то не то".
В общем я был уверен, что это имя херовое, но сам убедительных (для себя) аргументов не придумал и пошёл гуглить рекомендации по формированию диплинок.
И нагуглил, что кастомные схемы в диплинках - это дыра в безопасности в виде Deep Link Collision.
Из-за неё кто угодно может подписаться на наши диплинки. На андроиде в этом случае откроется диалог с вопросом в какое приложение перейти - наше или чужое (как вариант - с таким же именем и иконкой), а на иосе - вообще "If multiple apps register the same scheme, the app the system targets is undefined" 🤯
И это далеко не первый раз когда я на ревью начинаю докапываться до имени, а в итоге выхожу на серьёзный баг или проблему в архитектуре или просто нахожу лучшее решение, сформулированное в корректных терминах.
В общем мой совет: внимательно следите за именами в коде, кривые имена очень часто свидетельствуют о кривом коде.
На самом деле я считаю, что вопреки расхожему мнению, для разработчика [бакенда [информационных систем]] важнее умение хорошо писать на русском, чем "знать математику". Так что заводите свои блоги и каналы, чтобы практиковаться в письме и не делегируйте письмо ЛЛМкам:)
Если заведёте - пишите, напишу об этом в этом канале :)
#project_e@ergonomic_code
Apple Developer Documentation
Defining a custom URL scheme for your app | Apple Developer Documentation
Use specially formatted URLs to link to content within your app.
👍18💯4❤3
Привет!
Выпилил в #project_e поддержку АПИ в1 двухлетней давности.
Это примерно 7% всей кодовой базы проекта
Лучшее начало года, пожалуй, сложно представить:)
Ставьте лайк, если тоже больше любите коммиты, в которых удаляете код, а не добавляете новый:)
Выпилил в #project_e поддержку АПИ в1 двухлетней давности.
Это примерно 7% всей кодовой базы проекта
Лучшее начало года, пожалуй, сложно представить:)
Ставьте лайк, если тоже больше любите коммиты, в которых удаляете код, а не добавляете новый:)
👍30😁5🔥3
Привет!
Итоги 2025 года - лучше поздно, чем никогда, правда же?:)
Итог №1 - Больше реального кода
Больше всего сил в 2025 году (192 коммита, против 43 и 36 в вики и блог) я вложил в Trainer Advisor - публичный пример проекта, написанного по ЭП.
За 2025 год я в нём сделал 34 различных фичи и фикса, самые крупные и трудозатратные из которых были:
1. Интеграция с Гугл Календарями (PR, пост)
2. Пуш-уведомления (PR, пост)
В результате, TA дорос до 20К строк исходников и 20 таблиц.
Помимо этого в #project_e мы за прошлый год сделали пару новых сервисов и допилили новых фич в ядро на 2.2, 4.1 и 6К строк соответственно.
В итоге суммарное количество промышленного кода, написанного по ЭП, перевалило уже за 121 тысячу строк Kotlin и Java-кода.
Итог №2 - Эргономичная архитектура
Также значительным на мой взгляд итогом 2025 года стало появление Эргономичной архитектуры и её представление с помощью трёх проекций. Описание Эргономичной архитектуры всё ещё в статусе черновика и публичных обновлений не было давно, но за кулисами я весь четвёртый квартал 25-ого года работал над проекцией модели данных. С четвёртой попытки у меня вышел текст, который мне нравится, но ещё надо убрать исторические наслоения из ТА, чтобы он стал хорошей иллюстрацией и собственно добавить эту иллюстрацию.
Итог №3 - Исследование характеристик поддерживаемых кодовых баз
Затем, довольно много времени и сил я потратил на проведение исследования характеристик поддерживаемых кодовых баз backend-приложений. К сожалению, собрать достаточное количество анкет не вышло (хотя анкета всё ещё открыта и вы всё ещё можете её заполнить:) ), поэтому все эти усилия по большому счёту пошли прахом. Тем не менее, у меня появилось слабое, но подтверждение, что ЭП как минимум не вредит поддерживаемости:)
Итог №4 - Большие посты
На поприще блоггинга я смог написать два больших поста:
1. Вам не нужна Чистая архитектура. Скорее всего
2. Учимся читать SQL SELECT
А всего в блог и вики я добавил (немного пугающие) 6660 строк. Это не считая незакоммитанных черновиков:)
Итог №5 - Новые паттерны
Ещё в 2025 году у меня оформилось несколько паттернов, немного сокращающих трудозатраты на разработку (за счёт того, что не надо велосипед придумывать):
1. Переход на UUID v7 в качестве идов сущностей
2. Пресеты сложных фикстур
3. [Wire]MockServers
4. и ещё пачка более мелких см. историю коммитов
Итог №6 - +1см в направлении книги
Прошлый год начался с того, что мне написал проектный менеджер ИД Питер с предложением издать книгу. На этой волне я немного полежал в направлении книги, но переключился на исследование. Знаете как расшифровывается СДВГ? "Синдром дефицита Вау! Голубь!".
И вот в конце прошлого года ко мне пришёл представитель уже второго крупного издательства с тем же предложением. Мы с ним довольно серьёзно продвинулись в планировании книги и ред. коллегия была готова заключить договор на издание книги, но с условием, что авторский текст я сдам до конца 26 года. А я по ряду причин не готов на это подписываться, поэтому и в этот раз не срослось.
Но, держим пальчики, процесс потихоньку сходится, когда-нибудь книга обязательно будет:)
#ergo_approach@ergonomic_code #traineradvisor@ergonomic_code #ergo_book@ergonomic_code
Итоги 2025 года - лучше поздно, чем никогда, правда же?:)
Итог №1 - Больше реального кода
Больше всего сил в 2025 году (192 коммита, против 43 и 36 в вики и блог) я вложил в Trainer Advisor - публичный пример проекта, написанного по ЭП.
За 2025 год я в нём сделал 34 различных фичи и фикса, самые крупные и трудозатратные из которых были:
1. Интеграция с Гугл Календарями (PR, пост)
2. Пуш-уведомления (PR, пост)
В результате, TA дорос до 20К строк исходников и 20 таблиц.
Помимо этого в #project_e мы за прошлый год сделали пару новых сервисов и допилили новых фич в ядро на 2.2, 4.1 и 6К строк соответственно.
В итоге суммарное количество промышленного кода, написанного по ЭП, перевалило уже за 121 тысячу строк Kotlin и Java-кода.
Итог №2 - Эргономичная архитектура
Также значительным на мой взгляд итогом 2025 года стало появление Эргономичной архитектуры и её представление с помощью трёх проекций. Описание Эргономичной архитектуры всё ещё в статусе черновика и публичных обновлений не было давно, но за кулисами я весь четвёртый квартал 25-ого года работал над проекцией модели данных. С четвёртой попытки у меня вышел текст, который мне нравится, но ещё надо убрать исторические наслоения из ТА, чтобы он стал хорошей иллюстрацией и собственно добавить эту иллюстрацию.
Итог №3 - Исследование характеристик поддерживаемых кодовых баз
Затем, довольно много времени и сил я потратил на проведение исследования характеристик поддерживаемых кодовых баз backend-приложений. К сожалению, собрать достаточное количество анкет не вышло (хотя анкета всё ещё открыта и вы всё ещё можете её заполнить:) ), поэтому все эти усилия по большому счёту пошли прахом. Тем не менее, у меня появилось слабое, но подтверждение, что ЭП как минимум не вредит поддерживаемости:)
Итог №4 - Большие посты
На поприще блоггинга я смог написать два больших поста:
1. Вам не нужна Чистая архитектура. Скорее всего
2. Учимся читать SQL SELECT
А всего в блог и вики я добавил (немного пугающие) 6660 строк. Это не считая незакоммитанных черновиков:)
Итог №5 - Новые паттерны
Ещё в 2025 году у меня оформилось несколько паттернов, немного сокращающих трудозатраты на разработку (за счёт того, что не надо велосипед придумывать):
1. Переход на UUID v7 в качестве идов сущностей
2. Пресеты сложных фикстур
3. [Wire]MockServers
4. и ещё пачка более мелких см. историю коммитов
Итог №6 - +1см в направлении книги
Прошлый год начался с того, что мне написал проектный менеджер ИД Питер с предложением издать книгу. На этой волне я немного полежал в направлении книги, но переключился на исследование. Знаете как расшифровывается СДВГ? "Синдром дефицита Вау! Голубь!".
И вот в конце прошлого года ко мне пришёл представитель уже второго крупного издательства с тем же предложением. Мы с ним довольно серьёзно продвинулись в планировании книги и ред. коллегия была готова заключить договор на издание книги, но с условием, что авторский текст я сдам до конца 26 года. А я по ряду причин не готов на это подписываться, поэтому и в этот раз не срослось.
Но, держим пальчики, процесс потихоньку сходится, когда-нибудь книга обязательно будет:)
#ergo_approach@ergonomic_code #traineradvisor@ergonomic_code #ergo_book@ergonomic_code
GitHub
GitHub - ergonomic-code/Trainer-Advisor: Информационная система йогатерапевта и демонстрационный проект Эргономичного подхода
Информационная система йогатерапевта и демонстрационный проект Эргономичного подхода - ergonomic-code/Trainer-Advisor
❤8👍7🔥3
Привет!
У меня недавно в Проекте Э случилась поучительная и многогранная история. Эта история одновременно:
1. Иллюстрирует как именно глобальное изменяемое состояние усложняет поддержку кода. И соответственно, почему его стоит избегать.
2. Показывает, что зелёные тесты на внешнее API не гарантируют отсутствие тупых багов внутри.
#why_fp@ergonomic_code #ergo_testing@ergonomic_code #project_e@ergonomic_code
У меня недавно в Проекте Э случилась поучительная и многогранная история. Эта история одновременно:
1. Иллюстрирует как именно глобальное изменяемое состояние усложняет поддержку кода. И соответственно, почему его стоит избегать.
2. Показывает, что зелёные тесты на внешнее API не гарантируют отсутствие тупых багов внутри.
#why_fp@ergonomic_code #ergo_testing@ergonomic_code #project_e@ergonomic_code
Алексей Жидков
Глобальное состояние и тестирование через внешнее API - Алексей Жидков
https://azhidkov.pro/
В данном случае это не плохо, а с учётом того, что публикация должна быть сделана через Transactional Outbox - неизбежно. Но если у функции появляется 2 и более подобных смежных ответственностей - это уже хороший повод, чтобы их отцепить как раз через события. Это и упростит код реализации, и надёжность работы функции повысит, и тесты ускорит и упростит.
Или, если на самом деле в зависимости от параметров функция делает "(А и Б) либо (А и В)" - то её надо разбить на две отдельных функции, переиспользующие "А".
#ergo_approach@ergonomic_code #books@ergonomic_code #project_e@ergonomic_code
Или, если на самом деле в зависимости от параметров функция делает "(А и Б) либо (А и В)" - то её надо разбить на две отдельных функции, переиспользующие "А".
#ergo_approach@ergonomic_code #books@ergonomic_code #project_e@ergonomic_code
👍3🤔1
Привет!
У меня периодически спрашивают как обстоят дела с перформансом у ЭП в целом и функционального стиля + Spring Data JDBC в частности.
Я всегда говорил "У меня не хайлоад и мне всегда хватало - никогда не приходилось ничего целенаправленно оптимизировать".
И вот у нас Проекте Э планируется переход от ~0.5 (3 в утренний пик) RPS к штатным 17 RPS 24/7. Тоже, конечно, не супер хайлоад, но уже существенная нагрузка, которая откровенных косяков не простит.
Я соответственно пошёл мерить и к моему небольшому удивлению, бэк сходу вывез эти 17 rps в течение 10 минут. При том по прочим метрикам вывез без проблем и мог бы больше, но я пока не стал искать предел - есть более приоритетные задачи.
Единственное что, это был только первый этап и БД была практически пустая - 100К записей в целевой таблице, а с такой нагрузкой рабочий объём будет 500-600М записей.
Тестируемая операция:
0. авторизация по JWT-токену с парсингом и верификацией и с SELECT-ом его активности в БД
1. нетривиальный парсинг json-а с поддержкой 8 минорных версий схемы, валидация и дедупликация данных
2. один SELECT с локом по юзеру
3. пара простых SELECT-ов в целевую таблицу
4. маппинги DTO -> Domain -> Persistence
5. один INSERT в целевую Postgres inherited table
6. один простой INSERT в таблицу transactional outbox-а
7. асинхронно - публикация события в rabbit mq и удаление по id из outbox-а
Чутка цифр по запросам:
0. всего запросов - 14199
1. ошибок - 0
2. avg - 115.5ms
3. p90 - 151.8ms
4. p95 - 296.5ms
5. p99 - 511.9ms
6. max - 1968.9ms.
И по железу:
1. бэк - 1 pod в k8s с лимитами 400m CPU/750Mi RAM, JVM heap 550Mi. Вот тут я прям удивился, что spring-то оказывается мохёт на 500мб РАМ О_О. А в проде уменя зачем-то 2гб стоит.
2. Postgres - cloud.ru-шный менеджед на rds.pg.x1.large.2 | 2 vCPUs | 4 GB
17 RPS - тоже нифига не хайлоад, конечно, но уже и не стыдно людям рассказать.
#ergo_approach@ergonomic_code #spring_data_jdbc@ergonomic_code #project_e@ergonomic_code
У меня периодически спрашивают как обстоят дела с перформансом у ЭП в целом и функционального стиля + Spring Data JDBC в частности.
Я всегда говорил "У меня не хайлоад и мне всегда хватало - никогда не приходилось ничего целенаправленно оптимизировать".
И вот у нас Проекте Э планируется переход от ~0.5 (3 в утренний пик) RPS к штатным 17 RPS 24/7. Тоже, конечно, не супер хайлоад, но уже существенная нагрузка, которая откровенных косяков не простит.
Я соответственно пошёл мерить и к моему небольшому удивлению, бэк сходу вывез эти 17 rps в течение 10 минут. При том по прочим метрикам вывез без проблем и мог бы больше, но я пока не стал искать предел - есть более приоритетные задачи.
Единственное что, это был только первый этап и БД была практически пустая - 100К записей в целевой таблице, а с такой нагрузкой рабочий объём будет 500-600М записей.
Тестируемая операция:
0. авторизация по JWT-токену с парсингом и верификацией и с SELECT-ом его активности в БД
1. нетривиальный парсинг json-а с поддержкой 8 минорных версий схемы, валидация и дедупликация данных
2. один SELECT с локом по юзеру
3. пара простых SELECT-ов в целевую таблицу
4. маппинги DTO -> Domain -> Persistence
5. один INSERT в целевую Postgres inherited table
6. один простой INSERT в таблицу transactional outbox-а
7. асинхронно - публикация события в rabbit mq и удаление по id из outbox-а
Чутка цифр по запросам:
0. всего запросов - 14199
1. ошибок - 0
2. avg - 115.5ms
3. p90 - 151.8ms
4. p95 - 296.5ms
5. p99 - 511.9ms
6. max - 1968.9ms.
И по железу:
1. бэк - 1 pod в k8s с лимитами 400m CPU/750Mi RAM, JVM heap 550Mi. Вот тут я прям удивился, что spring-то оказывается мохёт на 500мб РАМ О_О. А в проде уменя зачем-то 2гб стоит.
2. Postgres - cloud.ru-шный менеджед на rds.pg.x1.large.2 | 2 vCPUs | 4 GB
17 RPS - тоже нифига не хайлоад, конечно, но уже и не стыдно людям рассказать.
#ergo_approach@ergonomic_code #spring_data_jdbc@ergonomic_code #project_e@ergonomic_code
PostgreSQL Documentation
3.6. Inheritance
3.6. Inheritance # Inheritance is a concept from object-oriented databases. It opens up interesting new possibilities of database design. Let's create …
❤2👍2😁1
Привет!
Не устали ещё от "(ещё большего) затишья на пару месяцев"? 😂
Самому страшно представить, что через два месяца начнётся 🤯
В общем я тут ещё немного поупражнялся с нагрузкой Проекта Э:
1. 2 ноды в cloud.ru по 4К в месяц
2. 1 менеджед постгрес по 4К в месяц
3. 2 пода с лимитами в ~25-50% от ресурсов ноды (1 из 4 гб РАМ на всё, 1 из 2 CPU)
4. при 70 rps в течении 10 минут - медианное время ответа 175мс, 99 персентиль - 616мс, максимум - 1470мс.
5. на 100 RPS под упёрся в CPU - скорее всего за недорого можно и на 100 RPS выйти, но для меня это уже явный оверкилл.
Попутно отловил прикольный косяк в реализации, которым на мой взгляд многие могут грешить.
У меня хэширование паролей при логине (тяжёлая операция на сотни миллисекунд) делалось внутри транзакции. Соответственно запросы логина во время ожидания хэширования выжирали весь пул подключений и тормозили целевые запросы.
Вобщем проверьте у себя - не делаете ли вы хэширование паролей (или другие чистые, но алгоритмически тяжёлые операции) внутри транзакций:)
#project_e@ergonomic_code
Не устали ещё от "(ещё большего) затишья на пару месяцев"? 😂
Самому страшно представить, что через два месяца начнётся 🤯
В общем я тут ещё немного поупражнялся с нагрузкой Проекта Э:
1. 2 ноды в cloud.ru по 4К в месяц
2. 1 менеджед постгрес по 4К в месяц
3. 2 пода с лимитами в ~25-50% от ресурсов ноды (1 из 4 гб РАМ на всё, 1 из 2 CPU)
4. при 70 rps в течении 10 минут - медианное время ответа 175мс, 99 персентиль - 616мс, максимум - 1470мс.
5. на 100 RPS под упёрся в CPU - скорее всего за недорого можно и на 100 RPS выйти, но для меня это уже явный оверкилл.
Попутно отловил прикольный косяк в реализации, которым на мой взгляд многие могут грешить.
У меня хэширование паролей при логине (тяжёлая операция на сотни миллисекунд) делалось внутри транзакции. Соответственно запросы логина во время ожидания хэширования выжирали весь пул подключений и тормозили целевые запросы.
Вобщем проверьте у себя - не делаете ли вы хэширование паролей (или другие чистые, но алгоритмически тяжёлые операции) внутри транзакций:)
#project_e@ergonomic_code
👍6
Привет!
Ну, моя эпопея с нагрузкой продолжается (часть 1, часть 2) и продолжает генерять материал для канала.
Я перешёл к этапу проверки работы с БД целевого размера (600М строк).
Идти решил постепенно: для начала залил 50М строк в целевую таблицу, запустил нагрузку и... Опять упрёся в ЦПУ на хэшировании паролей в транзакции при логине -> забитый пул подключений -> тормоза аутентификации целевого запроса на получении подключения для проверки активности токена.
Решил, что хватит извращений и надо залечить проблему с хэшированием в транзакции.
Залечил, запустил нагрузку, иии... Бэк начал 500-ить на логине. То есть стало хуже чем до фикса.
Полез копаться. Выяснилось:
1. я из транзакции вытащил чтение SDJ-агрегата, у которого было две связанных коллекции
2. т.е. это был не 1 запрос, а 1 + 2 (чтение корня + чтение коллекций).
3. при том второй запрос выполняется до завершения первого
4. и так как транзакции не было, SDJ для второго запроса захватывал новое подключение
5. в итоге 10 потоков логина на чтении корня агрегата выбирали все подключения из пулла, потом пытались сделать второй запрос и блокировались навечно, потому как все подключения уже были заняты предыдущим запросом корня, который ждал результатов запроса коллекций, который ждал... ну вы поняли:)
Завернул чтение агрегата обратно в транзакцию, запустил нагрузку (на 50М строк) и...
70 rps в течении 10 минут - медианное время ответа 137мс, 99 персентиль - 314мс, максимум - 1644мс.
т.е. в итоге корректный фикс срезал мидиану на 15%, а 99персентиль - на 30.
Мораль басни:
1. Не держите тяжёлые вычисления внутри транзакций
2. Но держите все обращения к SDJ внутри транзакций:) Вообще это прямым текстом написано в оф. доках - осталось только не забывать, не тупить и не лениться.
3. SDJ безусловно на порядок-два проще Hibernate, но всё равно слишком сложен для кожанного мешка
#spring_data_jdbc@ergonomic_code #project_e@ergonomic_code #ergo_approach@ergonomic_code
Ну, моя эпопея с нагрузкой продолжается (часть 1, часть 2) и продолжает генерять материал для канала.
Я перешёл к этапу проверки работы с БД целевого размера (600М строк).
Идти решил постепенно: для начала залил 50М строк в целевую таблицу, запустил нагрузку и... Опять упрёся в ЦПУ на хэшировании паролей в транзакции при логине -> забитый пул подключений -> тормоза аутентификации целевого запроса на получении подключения для проверки активности токена.
Решил, что хватит извращений и надо залечить проблему с хэшированием в транзакции.
Залечил, запустил нагрузку, иии... Бэк начал 500-ить на логине. То есть стало хуже чем до фикса.
Полез копаться. Выяснилось:
1. я из транзакции вытащил чтение SDJ-агрегата, у которого было две связанных коллекции
2. т.е. это был не 1 запрос, а 1 + 2 (чтение корня + чтение коллекций).
3. при том второй запрос выполняется до завершения первого
4. и так как транзакции не было, SDJ для второго запроса захватывал новое подключение
5. в итоге 10 потоков логина на чтении корня агрегата выбирали все подключения из пулла, потом пытались сделать второй запрос и блокировались навечно, потому как все подключения уже были заняты предыдущим запросом корня, который ждал результатов запроса коллекций, который ждал... ну вы поняли:)
Завернул чтение агрегата обратно в транзакцию, запустил нагрузку (на 50М строк) и...
70 rps в течении 10 минут - медианное время ответа 137мс, 99 персентиль - 314мс, максимум - 1644мс.
т.е. в итоге корректный фикс срезал мидиану на 15%, а 99персентиль - на 30.
Мораль басни:
1. Не держите тяжёлые вычисления внутри транзакций
2. Но держите все обращения к SDJ внутри транзакций:) Вообще это прямым текстом написано в оф. доках - осталось только не забывать, не тупить и не лениться.
3. SDJ безусловно на порядок-два проще Hibernate, но всё равно слишком сложен для кожанного мешка
#spring_data_jdbc@ergonomic_code #project_e@ergonomic_code #ergo_approach@ergonomic_code
Telegram
Эргономичный код
Привет!
У меня периодически спрашивают как обстоят дела с перформансом у ЭП в целом и функционального стиля + Spring Data JDBC в частности.
Я всегда говорил "У меня не хайлоад и мне всегда хватало - никогда не приходилось ничего целенаправленно оптимизировать".…
У меня периодически спрашивают как обстоят дела с перформансом у ЭП в целом и функционального стиля + Spring Data JDBC в частности.
Я всегда говорил "У меня не хайлоад и мне всегда хватало - никогда не приходилось ничего целенаправленно оптимизировать".…
❤3