Обновить
9
31.1
Денис@Snaret

Java developer

Отправить сообщение

Информационная система всё равно хранит и изменяет состояние, а делают изменения процессы.

Все верно. И в этом проблема, процессы построены на связи микросервисов через средства (Rest, gRPC и тд), которые в свою очередь ломаются и не доходят. Бизнес-логика начинает зависеть от того, как именно мы связали сервисы. Я хочу от этого уйти.

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

И тут все верно, но в микросервисном мире эти правила размазаны между ними. То есть в одном сервисе 1я часть правил, во 2м вторая и так далее. В итоге согласованность - это не свойство модели, а эффект взаимодействия нескольких компонентов. Хотелось бы собрать эту логику в одном месте и сделать её атомарной и транзакционной.

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

В классическом оркестраторе согласованность данных является следствием корректно выполненного процесса: если все шаги A - B - C отработали, то состояние считается валидным. Если что-то не дошло — добавляются ретраи, компенсации и т.д. Я сознательно хочу перевернуть приоритеты. Первично не "какие шаги нужно выполнить2, а "какие инварианты состояния должны быть истинны после любого события".
Процессов как таковых Engine не знает - он лишь применяет правила, пока состояние не станет согласованным, либо откатывается.

Внешне Engine действительно может выглядеть как оркестратор с жёсткой транзакцией. Отличие для меня в том, что порядок действий не кодируется явно и не является частью бизнес-логики - он выводится из зависимостей/правил между состояниями.

Я согласен, что внешне это похоже на оркестрацию, потому что есть центральный компонент. Разница для меня не в топологии, а в том кто за что отвечает.

Оркестратор управляет процессами, сделай A → потом B → если не получилось — компенсируй C, а моя идея управляет состоянием данных.

Идеи схожи, но отличие именно в модели мышления process-first и state-first

Спасибо за статью!

На мой взгляд немного не хватило теоретической глубины)

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

Спасибо за статью)

Не всегда Вам в pipeline дадут доступ к докеру. В этом случае могу порекомендовать Zonky который поднимет postgresQL в памяти без всяких контейнеров. Удобно и ощутимо быстрее чем с контейнерами.

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

Погуглите проект Valhalla

Это да. Уже не раз встречал и каждый раз страдаю)

Сразу хотел добавить демонстрационный код, но побоялся из-за объема. Сейчас подумал и добавил)

Спасибо за подсказку, добавил)

Ну на поверхности или нет, но очень часто вижу, что многие этого вовсе не знали)
Аргументов в пользу field injection кроме как удобства нет)

Ничего не понятно, но очень интересно...

https://copyleaks.com/ru/ai-content-detector
https://isgen.ai/ru


Чтобы было меньше сомнений. Так пишешь-пишешь пол дня, а потом ты - ллм)

Можно все программирование свести к одной табличке. Но глубокого понимания причин того или иного решения это не даст. Этим скорее всего и отличаются кодеры от программистов.

Это не проблема в глобальном смысле, пока ты не начинаешь бороться с чистотой и производительностью кода. Странно то, что многие, в том числе из перечисленных в конце статей, не до конца осознают из-за чего это все происходит.

В целом наверно Ваше мнение поддерживает большинство. Но я так не хочу)

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

Вы абсолютно правы, JPA-сущности (@Entity) требуют конструктор по умолчанию. Но это другой тип класса с другим жизненным циклом, управляемым Hibernate, а не Spring DI. Мы говорим о сервисах, компонентах и репозиториях (@Service@Component@Repository), где вся логика работы строится на зависимостях, и их целостность критична.

Так это и проходит красной нитью через весь текст)

"К моменту завершения конструктора все инварианты должны быть выполнены. Объект, вышедший из конструктора, обязан быть целостным (consistent) и готовым к работе."

Я бы вам порекомендовал в качестве дто использовать не объекты из OpenApi, а из JOOQ. Там и record'ы есть для спокойной передачи данных

Спасибо за статью, позволю себе несколько замечаний по коду (так сказать ревью):

  • Mono<@NonNull Void> - крайне спорно и по-моему бессмысленно

  • в UserService отсутствует обработка ошибок. Вообще.

В целом подозреваю, что все это сделано из-за быстроты и генерации части кода OpenAPI Generator. Советую поставить openApiNullable: "true".

Есть непонятный мне конфликт:
useOptional: "true", //Использовать Optional
openApiNullable: "false", // Но ничего не может быть null?!

В тесте вообще не пойму откуда User user = new User();

Ведь если это DTO из OpenAPI то как минимум в коде вижу UpdateUser. Да и что UpdateUser делает в createUser методе?)

В github вообще не нашел папки по пути ru.maximserver.vmuserservice.model указанные в сервисном слое.

Очень много загадочного в проекте на мой взгляд))

Прошу простить, что надушнил, но кто-то(например я) захочет что-то изучить по вашему коду и столкнется с множеством проблем.

Спасибо за мнение!

Я подумаю насчет статьи. А пока скажу, чтоsynchronized напрямую манипулирует Mark Word объекта для реализации легковесных блокировок, аReentrantLock вроде использунт механизм AQS, который практически не влияет на Mark Word самого защищаемого объекта, а иногда даже не требует отдельного объекта для блокировки

Информация

В рейтинге
251-й
Откуда
Россия
Дата рождения
Зарегистрирован
Активность

Специализация

Бэкенд разработчик
Средний
От 250 000 ₽
Java
SQL
REST
Spring Boot
Hibernate
ООП
Docker
Redis
Apache Kafka
PostgreSQL