Цікаво, які відгуки про Хорватію від знайомих? Наскільки розвинутий місцевий ринок IT, наскільки складно отримати ВНЖ/ПМЖ?
А нахіба це мокати? docker compose up і будь яка база у вас
Проблема ж не у тому щоб підняти базу. Проблема її ініціалізувати даними під кожний окремий бізнес кейс який необхідно покрити юніт тестами. А також зачищати дані які змінилися як результат роботи тесту (ну або заново ініціалізувати контейнер перед кожним юніт тестом, що у сумі вже досить довго якщо тестів тисячи). Плюс якщо тести запускаються у паралель на тих самих даних, дані змінені одним тестом легко ломають композицію даних підготовлену для іншого тесту. Підтримувати купу таких ініціалізацій у вигляді SQL скриптів або коду той ще головняк, усе це за рік-другий перетворюється на мес. Для сервіс тестів це ок, але сервіс тести зазвичай покривають лише основні сценарії і їх значно меньше порівняно з юніт тестами.
У загальному випадку Domain Model та DB Model можуть доволі сильно відрізнятися, особливо з часом. Використання IDbSet / IQueryable напряму зв’язує руки у оптимізації DB моделі в майбутньому. При зміні DB моделі усі ці INCLUDE, WHERE і т.п. доведеться змінювати у бізнес логіці в купі місць. Тому на довготривалих проектах де є доменна модель у більшості випадків класичний репозиторій який приймає та повертає об’єкти саме доменної моделі більш гнучкий варіант. У внутрішній реалізації Data Access якщо клас доменної моделі збігається зі структурою таблиць можно і напряму замапити. Ні — додати внутрішні класи ДБ моделі які і будуть мапитися EF + мапінг кодом між класами DB та доменної моделі. Якщо потрібен складний запит та EF генерить єресь — викидаємо запит через EF і додаємо гарно оптимізовану SP. І це все прозоро для бізнес логіки / доменної моделі.
Для read моделі, де потрібна куча різноманітних проекцій тільки для того щоб віддати їх через API, — IQueryable напряму може бути непоганим варіантом.
Якщо проект це 1500 довідників з тупим CRUD, доменної моделі як такої немає, моделі API контрактів майже збігаються з ДБ моделлю, — IDbSet напряму може бути оптимальним варіантом.
Який варіант оформлення (ЕООД, ЕТ тощо) є найкращим?
Зазвичай для IT обирають між «Свободна Професия» (максимально схоже на український ФОП) та ЕООД. ЕООД може бути трохи вигідніше якщо дохід меньше ±3000EUR/міс, СП — якщо вище, бо є максимальна сума з якої рахуються соціальні внески.
ЕТ, теоретично, теж можливо, але він буде менш вигідним по податках порівняно з СП, якщо немає великих витрат. За СП вважається що 25% доходу йдуть на витрати (тобто податок платиться на 75% доходу). Це бай дифолт, за законодавством, без необхідності підтверджувати документами. За ЕТ також можно списувати витрати, але за наявності документів.
Що для першого що для другого потрібно вже мати або ВНЖ або ТЗ.
Чи можна на цій підставі отримати Blue Card
ні
або інший ВНЖ замість тимчасового захисту
Теоретично, можно спробувати ось це www.az.government.bg/...ost-na-svobodna-praktika Але потрібна болгарська рівня B1 та складений бізнес план і чув що цей варіант не дуже охоче дають під IT фріланс.
Якщо обираєте ТЗ, майте на увазі, що його буде дуже складно (майже неможливо) змінити на інший статус, наприклад на Blue Card, до завершення статусу ТЗ. Болгарське законодавство в цьому питанні не дуже логічне, і хотфіксять його тільки якщо вже ну зовсім ніяк.
Якщо мета легалізація, — найкращим варіантом може бути знайти болгарського роботодавця який буде готовий допомогти з блю кард, ДО оформлення ТЗ.
До плюсів, не за темою топіку, є відносно прості варіанти отримати ВНЖ, і через 5 років громадянство. Вартість купівлі житла, навіть у туристичних районах, десь на рівні умовної Софії. До мінусів, — чув що рахунки для фізичної особи в місцевих банках тільки в песо. Якщо не фріланс, — більшість офісів компаній у Гвадалахарі та Мехіко, які вже менш цікаві для життя.
У Playa del Carmen і Tulum досить багато європейців та американців що купують апартаменти та живуть. Не виглядає що є проблема з купівлею. Багато пропозицій на інвестування. За рівнем злочинності штати Yucatan та Quintana Roo вважаються відносно безпечними. Особливо туристичні райони. Звісно, є і райони де іноземцю краще не суватись, особливо вночі, але де їх немає? Довелося якось пів року там прожити, взагалі місцеві ну дуже приємні, спокійні та доброзичливі. Буйної чи агресивної молоді взагалі жодного разу не бачив, на відміну від багатьох, навіть європейських країн.
Цікаво було б почути якесь офіційне тлумачення. За логікою назви малоймовірно що така віза відкриває шлях до подальшої легалізації. Але якщо дійсно так, то досить цікавий варіант.
Так, воно саме так і працює. Якщо вже є дозвіл на проживання (або класичний ВНЖ, або захист) ви можете відкрити свободну професію за алгоритмом який описаний тут nra.bg/...dohdite/svobodni-profesii Тоді вимог що ви описали немає. Якщо хочете зайти з «нормального» ВНЖ, тоді через візу D та дозвіл, при цьому вже є ці вимоги. І так, свободну професію відкриту на підставі захисту на разі неможливо сконвертувати в повноцінний ВНЖ.
До речі, для Болгарії диплом не потрібно апостилювати, бо це одна із небагатьох країн з якими діє угода про взаємне визнання офіційних документів. Єдине що може знадобитись це переклад в будь якому бюро перекладів.
Для вас найбільшим челенджем може бути відкриття рахунку у банку. Є банки що відмовляють не те що з Луганською а навіть з Харківською / Херсонською / Запорізькою пропискою.
Для IT вам потрібна «свободна профессия» це як раз майже аналог українського ФОП. Знайомі на тимчасовому захисті відкривали без проблем. Процес відкриття майже такий самий як в Україні до появи Дії. Трохи більше звітності, краще найняти бухгалтера на перший час. ЕТ то трохи про інше, не для IT.
Я скоріш не про ексклюзивне блокування в сенсі БД, а про логічне блокування бізнес операцій над одним і тим самим об’єктом та деяких операцій в цілому при горизонтальному масштабуванні.
Приклад 1.
Банківська транзакція. Читання з бази — міллісекунди, оновлення в базі міллісекунди, для сабміту на 3rd party потрібна взаємодія з декількома сервісами з SLA
Приклад 2.
Умовний батчінг процес 10 секунд — 2 хвилини. В кластері
Звісно що існує багато інших способів вирішення, але розподілені логічні блокування це один із них.
Але ж у такому разі потрібно тримати відкритий конекшн протягом усього процесу. Якщо взаємодія з базою займає невеликий процент часу, 2% часу читання, 96% часу обробка, взаємодія з іншими сервісами, та 2% часу оновлення, то навіщо тримати конекшн? Кількість конекшенів все ж таки обмежений ресурс. До речі не звернув увагу на це, це як на мене ще один з мінусів ціх стандартних реалізацій.
Нажаль, в стандартних реалізаціях від СУБД не вистачає динамічного таймауту. Тобто, є деякий процес, операція над об’єктом, тощо, який має виконуватись одночасно лише на одному із багатьох інстансів сервісу. Але час виконання може бути як 1 секунда так і десятки хвилин в залежності від обставин. Тобто фіксований таймаут не дуже підходить. Доки інстанс «живий» і продовжує виконувати операцію, блокування повиненне утримуватись. Але якщо інстанс жорстко крешнувся (з тих чи інших причин) потенційно finaly де знімається лок, може не відпрацювати. Тому безкінечний таймаут також не підходить, бо можна отримати вічне блокування. Один із способів вирішення цієї проблеми, це вимірювання таймауту від останнього heartbeat-у. Але ж для відправки heartbeat-ів так чи інакше по перше потрібна SP / функція яка їх приймає, по друге обв’язка у коді яка їх у фоні відправляє.
Хєх, але перевірив, таки так, в MySQL другий SELECT дійсно повертає існуючі дані без очікування навіть з WHERE не за PK, доки його в транзакцію аж з рівнем SERIALIZABLE не обгорнути.
Не використовував (або вже забув що використовував ))) )SELECT FOR UPDATE на практиці, коли потрібно як раз Distributed Locks використовуємо щоб не тримати конекшн відкритим, але як на мене трохи дивна поведінка. Припустимо у мене є таблиця с бонусами. Id, UserId, BonusAmount, BonusDateTime. З одного інстансу сервісу я відкриваю транзакцію і роблю SELECT FOR UPDATE по Id, тобто блокую одну строку для того щоб збільшити Amount на деякий процент. З іншого інстансу сервісу мені потрібно при наданні нового бонусу перевірити що цього дня по UserId ще не було бонусів. Тобто роблю SELECT по UserId + BonusDateTime. Але ж друга транзакція не знає що перша буде саме Amount змінювати а не UserId чи BonusDateTime. Тобто якщо друга транзакція робить SELECT не за PK (Id) а за комбінацією полів та рівень ізоляції вище ніж READ UNCOMMITTED я б скоріш очікував що вона повинна дочекатися зняття локу на UPDATE.
Ну почему сразу на мусорке :) Внутри Data Access Layer, для многих случаев вполне себе может жизнь упростить. Там же его можно и комбинировать с написанными с любовью SQL запросами )) Главное не светить всей этой радостью наружу интерфейсов репозиториев ни в явном ни в неявном виде. Может разве что за исключением рид моделей, и то я бы поспорил, слишком неявно когда один наделает цепочек свойств с той же ленивой загрузкой, а другой гуляет по ним без задней мысли что бомбардирует базу десятками запросов.
ДДД/гексональна архітектура
ДДД != гексональна архітектура
хопа — монго на касандру поміняли!
Із практики: хопа і GDPR => хопа і потрібно зберігати частину даних в окремій базі у зашифрованому вигляді. І при цьому об’єкт потрібно зібрати з декількох баз або навіть сервісів. В одному випадки ви лише змінюєте внутрішню реалізацію репозіторію, у випадку з лейзи лоадінг (де ви де факто зав’язані на можливості ОРМ) вам буде дуже боляче.
або сподіваючись
Не сподіваючись, а розпитуючи у бізнесу реальні сценарії. Інакше ви будете оптімізувати те, що нікому взагалі не потрібно і чого ніколи не станеться. Замість того щоб сконцентруватися на оптимізації реальних сценаріїв.
OrderItems завжди завантажуються? Навіть для completeOrder?
Якщо ви маєте на увазі кінцевий стан, то у вас вже немає мутацій, читайте як хочете використовуючи рид модель.
У key-value БД може і не проблема весь документ витягувати, але для реляційних БД це занадто дорогий підхід.
Ну то використовуйте технічні інструменти які більш оптимальні для вашої задачи.
де агрегат в рядок таблиці влізає, а колекції і колекції колекцій.
Тут інше питання, як буде виглядати код і скільки буде коштувати його підтримка якщо ви будете особливим чином вибирати дані під кожен сценарій агрегату. І так, якщо дійсно буде проблема з перформансом, то можливо вам доведеться це робити. Але у багатьох випадках це може означати що у вас невірно вибрані границі агрегату.
Якщо правильно зрозумів, у ДДД домен — це бізнес-суть, ентіті — це домен + id (і, скоріш за все, version),
Не впевнений що ви правильно це розумієте.
Спочатку у сенсі DDD. Entity це частина бізнес моделі, яку вам потрібно відслідковувати і змінювати на проміжку часу що має сенс з точки зору вашого бізнесу. Коли мы говоримо про identity, ми маємо на увазі логічну унікальність з точки зору бізнесу.
Наведу такий приклад, у вас є програма лояльності та учасник програми лояльності LoyaltyMember. У фізичному житті це людина. З точки зору бізнесу вам важливий проміжок часу з моменту реєстрації у програмі лояльності до виходу із програми лояльності. Тому що вам потрібно нараховувати та списувати бонуси. Якщо одна і таж фізична людина вийде з програми лояльності, а через рік вирішить зареєструватися знов, вам може бути не цікаво з точки зору бізнесу що це знову таж сама людина. У вашому бізнес домені це вже новий LoyaltyMember, якому ви нараховуєте бонуси з нуля. Це логічна унікальність.
У ролі логічної унікальності може використовуватись як бізнес властивість, наприклад номер картки лояльності, ключова умова, ця характеристика не повинна змінюватись протягом логічного життя бізнес сутності, так і сурогатний Id (автоінкремент, GUID і т.п.), який формально не є частиною домену, але дозволяє технічно ідентифікувати збережений бізнес об’єкт.
І тут ми повільно переходимо до технічної реалізації. Навіть якщо ви використовуєте бізнес властивість у якості унікального ключа, на рівні DataAccess технічно простіше оперувати сурогатними ключами. І тут у нас з’являється сурогатний Id який ми можемо використовувати наприклад в джоінах.
Version це так само технічна частина, яка, наприклад може допомогти в контролі паралельного доступу (наприклад реалізації оптимістичних блокувань) інвалідації кешу і т.п. Але наврядчи ваш бізнес оперує поняттям версії учасника програми лояльності. У той же самий час, якщо вам технічно треба мати версію на рівні класів Domain Model, не бачу великого сенсу її не добавити тільки тому що це не відповідає догмам.
Гадаю, в загальному випадку можна прийняти, що читання «як один документ» вдарить по перформансу.
Загальний випадок це абстрактний кінь у вакуумі.
Бо в кожному випадку можуть бути різні кордони агрегату. Умовно, атачмент як файл це не частина проекту, але проект містить референс на збережений файл.
Також з точки зору конкретного домену можуть бути логічні рестрікшени з огляду на які технічні проблеми які ви вирішуєте, можуть взагалі не бути проблемами у реальному житті. Умовно, ви вирішуєте як оптімізувати загрузку графа з мільйоном тасок. А на практиці у 99% юзерів буде не більше
Досить умовна схема:
1. Завантажити агрегат.
2. Перевірити те, що команда може бути виконана на поточному стані агрегату.
3. Мутувати агрегат (операція може бути імперативною, де класична Rich Model перевіряє себе та мутує себе, або функціональною, де state може бути виражений за допомогою імутабельної Anemic Model (яка не обов’язково дорівнює Data Model), бізнес операції за допомогою чистих функцій, умовно Project state n+1 = CompleteTask(Project state n, taskId), але ви повинні гарантувати що наступна команда буде виконуватись на Project state n+1).
4. Зберегти зміни.
Якщо у вас є черга команд, п.1 можно виконувати не для кожної команди, а для пачки команд із черги. Після п.4 беремо наступну команду із черги і переходимо до п.2. На схожому принципі побудована т.з. Actor Model.
Команди повинні аплаїтись послідовно, навіть якщо немає черги (або песімистичне блокування ДО завантаження, на період виконання команди, або оптімістичне блокування) інакше п.2 може дати помилковий результат.
Цікава стаття. Але її оцінять десь через рік-два. Взагалі нічого не змінюється, все як завжди: хайп «чому ви всюди повинні використовувати інструмент N, бо це нова срібна куля»
-> хайп «чому ви не повинні використовувати інструмент N за жодних умов, бо від нього суцільні проблеми» -> нарешті «де і як варто використовувати цей інструмент, бо від нього є користь, і де не варто, бо проблем більше, ніж користі». Ось на цьому етапі інструмент стає зрілим, а євангелісти та хейтери вже хайпують на інструменті N+1. Звісно, масштаб цього разу в рази більший, бо бабок вгупали на порядки більше.
Не зрозуміло, чому євангелісти взагалі сприйняли статтю як хейт. Не бачу тут жодного хейту, а питання про методики використання і оновлення процесу досить доречне.