На співбесіді мене попросили написати «костиль»

Знову п’ятниця, тож час невигаданих історій!

Нещодавно в мене була технічна співбесіда в компанію Argus (аналітика даних, цін на світові енергоносії, все як я люблю)

Першим питанням було як завжди — розкажіть кейси з практики, якими ви пишаєтесь.

Кажу, взагалі я пишаюсь всіма своїми розробками, та не встиг навести конкретний приклад, як почув хамовате — «Дааа? Та що ви кажетеее!»...

Ось та цьому токсичному коменті вже треба було закінчувати розмову, але було цікаво які челенжи вони підготували для мене.

То ж ми перейшли до основної задачі.

Ведучій інтерв’ю відкрив гугл-боард і почав малювати «архітектуру».

Оце — мікросервіс, який слухає 2 типи івентів «OrderCreated» (складає json в базу) і «SendInfoToPartner» з айдішкою ордера — дістає ордер з бази і дьоргає якусь зовнішню апішку.

Проблема — івент «SendInfoToPartner» приходить раніше, ніж ордер було збережено в базу. Як ви вирішете це?

Одразу відкинувши варіанти з повторними опитуваннями бази на наявність ордера, я запропонував 2 варіанти:

1. Якщо це база по типу AWS DynamoDb, вона може бути джерелом івентів для лямбда функції, коли в неї додається новий запис. Хендлер SendInfoToPartner винести в ламбду. (коментар від інтерв’юера — о, а що DynamoDb так вміє?)

2. Створити якийсь окремий стрім типу Redis Pub/Sub, через який SendInfoToPartner буде отримувати повідомлення від OrderCreated, що ордер записаний в базу.

Жоден з цих варіантів не влаштував інтерв’юера і він з гордістю почав малювати як вони вирішили цю проблему — quick and dirty fix:

В базі даних вони створили додаткову колонку/поле (не знаю що в них там), з ознакою того, що хендлер «SendInfoToPartner» туди приходив і не знайшов ордер — 1. Коли хендлер «OrderCreated» приходить писати ордер в цю табличку, він дивиться на це поле, і якщо там стоїть 1, то хендлер «OrderCreated» напряму викликає хендлер «SendInfoToPartner».

Я дивлюсь на це рішення і в голові лише одніа думка — а з якою метою ти виніс цей шматок г..на на співбесіду? Ти загадив таблицю нерелевантними даними своєї інфраструктури. Цей «мікросервіс» взагалі не повинен існувати в цьому вигляді. Що ти хотів побачити і що хотів цим показати?

В своїй практиці я проводив десятки співбесід. Саме круте, це коли кандидат виходить вдячний зі списком того, що йому треба підтягнути, і взагалі кайфонув від спілкування з крутими професіоналами.

Що отримав я з цієї співбесіди? Розбір якогось корявого «костиля», цінність якго нуль, а ще токсичне спілкування.

Пишіть, що думаєте про це, а також свої варіанти рішення, цікаво)

👍ПодобаєтьсяСподобалось12
До обраногоВ обраному0
LinkedIn

Найкращі коментарі пропустити

DynamoDB? Лямбди? Redis? Чого не запропонували створити окремий кафка кластер під стріми, якийсь там Apache Flink? і вже по нормальному робити репартішин і джоїнити стріми.

Масштабніше треба, масштабніше, тай пятничний вкид має бути масштабніший

у чуваків норм костиль, заімплементили і пішли далі пиляти систему, а не обоардити щє одну платформенну хєрню і потім пояснювати інвесторам чому найняли щє одного dev-ops’a и чому кости на клауд виросли і потім через півроку лей-оффи і автор знову ходить по співбесідах

Якшо вже по феншую:
тут стандарний кейс з прекондішинами і стейт машиною, де замість окремого філда треба було робити ентіті яка відповідальна за «дьоргає якусь зовнішню апішку» яка щє й покриває аудит (включно результат виклику) і ретраї якшо зовнішня апішка просралась і тд і тп
Але то вже більш розширена версія їхнього костиля і мабуть у команди є більше пріорітетні таски ніж застрягати з комплексним рішенням на якійсь фігні.

Чому в нього dirty а у вас — ні?

По факту ваш варіант при відсутності redis’a та dynabodb змушує їх ставити, налаштовувати і витрачати час на їх підтримку. А запропонований компанією можна зробити за 5хв і воно буде працювати так само як і ваш, тільки для бізнесу це буде дешевше

Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Одразу відкинувши варіанти з повторними опитуваннями бази на наявність ордера, я запропонував 2 варіанти:

1. Якщо це база по типу AWS DynamoDb, вона може бути джерелом івентів для лямбда функції, коли в неї додається новий запис. Хендлер SendInfoToPartner винести в ламбду. (коментар від інтерв’юера — о, а що DynamoDb так вміє?)

2. Створити якийсь окремий стрім типу Redis Pub/Sub, через який SendInfoToPartner буде отримувати повідомлення від OrderCreated, що ордер записаний в базу.

Жоден з цих варіантів не влаштував інтерв’юера і він з гордістю почав малювати як вони вирішили цю проблему

Вибачте але ваші варіанти не вирішують проблему. Ви просто додали ще одне джерело івентів. Про те як ваші варіанти вирішують проблему ви нічого не написали, а можливо й не сказали на співбесіді. Тому ваші варіанти й були відкинуті.

Як вже правильно помітили, SendInfoToPartner — це не подія, а команда та її правильніше відправляти через той самий REST API.
Але навіть якщо її відправляти як подію, то тут справді є проблеми і з data flow, і з цілісністю даних.
Як простіше зробити, без милиць — це відправляти подію OrderCreated з опцією sendInfoToPartner, і відповідно ваш мікросервіс буде відправляти або не відправляти дані в сторонній API.
Але навіть якщо так зробити технічно неможливо (наприклад, джерела цих повідомлень це різні мікросервіси), то нехай вони надсилають подію в один Kafka topic, де ключ — orderId.
Таким чином, подія SendInfoToPartner завжди буде після OrderCreated і замовлення буде збережено в базі, коли почнеться обробка SendInfoToPartner.

Взагалі, задачка має потенціал перерости в цікаву змістовну дискусію про типи consistency, delivery guarantees, idempotency, CAP-теорему врешті-решт, якщо обидві сторони розуміють, про що йдеться

*дістаю кришталеву кулю
SendInfoToPartner — виглядає як команда. Оскільки вистачає буля для пересилки, значить партнер строго один. Тобто виглядає як необв’язкова частина створення ордеру.

Оскільки вони знають про рейс кондішн, то кнопка сендТуПартнер десь під їх контролем. Тому було б непогано або замінити цю кнопку на галочку при створенні ордеру, щоб ця інформація пішла в перший івент.

Якщо я помиляюся, то було б непогано зробити, наступним чином: SendInfoToPartner тільки пише кудись дані (ордер, куди слать).
Створення ордеру кидає івент «Ордер створився»
Хендлер цього івенту перевіряє, чи треба ордер кудись послати за даними з першого кроку, і шле.
Так, за допомогою 1 івента (який і так не зайвий буде) та ще одного хендлеру, ми спрощуємо сейв та робимо кожну функцію відповідальною за 1 штуку.

Висновок — автрор оверінжинірить. Інтервьюер можливо трози недоінжинірив, але то вже питання більше до ресурсів.

Чому писати в сутність ордеру так собі ідея — оскільки ордеру ще нема, то воно де факто запише кортеж (ордерАйді, чиТребаСлатиВсіЗнаютьЯкомуПартнеру). Якщо створення ордеру може сфейлити — тепер ці дані з нами навічно, і доведеться це потім чистити.

доречі, good point про що буде, якщо виникне помилка при записі ордеру

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

Але ж SRP. Тепер таблиця ордерів робить 2 штуки, зберігає ордери і помилки інгерації. Воно може так само бути в окремій таблиці/чи будь-якому датасторі. Select * from SendToPartnerRequests where RequestProcessed = false як на мене трохи краще ніж select * from orders where SendToPartner = true and RequestProcessed = false. Складність треба свідомо зменшувати, росте вона й сама непогано:)

так. Особисто я теж не зберігав би в одній таблиці без додаткових вводних. Проте в принципі можна придумати і причину писати саме в одну таблицю. Наприклад це спроба підтримувати нативну послідовність записів без додаткових індексів. або свідоме порушення практик задля усунення гонки умов чи задля атомарності операції чи для зменшення кількості запитів.

це нарушен тотальний порядок, є трі варіанта:

* зафіксувати апстрім
* випрямляти
* відшибати як невалідний стан

я так розумію вони використували випрямлення (другий варіант), не бачу
чого такого костильного в рішенні, єдине що, я б зберігала
в базі айді та send_requested_at, send_completed_at.
якщо є реквест, нема компліту, та є дані, то відправити

інший варіант, це зберігати невалідни евенти окремо і раз на деякій
час (по крону) випрямляти

архітектурно «випрямітель» є сенс зробити даунстрімом
для істоку, та апстрімом для сервісу, щоб можна було його реюзнути
для різних систем

прикольно, дякую за проблему на подумати

Якщо меседж про створення ордера приходить пізніше ніж меседж про то, що з ордером вже щось встигло трапитись, то треба було почати з того що ви алєні і фіксить треба не наслідок а причину.

Але якщо питання саме в фіксі тут і зараз, то це вирішується тупим ретраєм з делеєм, просто очікуєм поки OrderCreated долетить та закоммітиться в базу.

Цей ордер може приходити із зовнішньої системи (як і виклик SendInfoToPartner), тому «фіксить причину» може і не вийти.

Автор не надав жодної додаткової інформації по системі (цікаво, чи запитував в інтервʼювера — схоже, що ні), тому однозначно відповісти, яке рішення підійде — не вийде.

Костыли не пишем, идем к PO/TL той команды которая чушь шлет и на этом вся таска закрыта. Если им так хочется булщита написать пусть сами его пишут в своем проекте, а вы поищите получше, где меньше говнокода или криворуких ивент сорсеров. Просто дропайте такие события как фейковые, сами виноваты. Написание костылей очень неблагодарное занятие, потом его нужно править время от времени и навешить еще костыль на костыль. А через полгода вы откроете свой говнокод и вообще не вспомните как оно работало

так просто не пиши говнокод. Чом ти на інших то проецируєш?

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

і тут ажіотажна купівля квитків на леді rary і через цей time.sleep все лягає від буквально десятка користувачів, дві третини з яких навіть не купують нічого.

на любом api gateway задается rate limit чтоб не убили бэк запросами и все. В это время другая команда судорожно ночью фиксит багу с ранним приходом SendInfoToPartner, за ночь готов хотфикс и деплой в пятницу на прод)

rate limit

і тоді запити будуть ставати в чергу доки вона не заповниться.
метод зі sleep підійде тоді, коли ти повністю більш-менш контролюєш процеси. Ну, там, воркер може почекати трохи. Кількість воркерів ти контролюєш. А от якщо запити прилітають з умовного фронту, то сліпати кожен запит так собі план.

команда судорожно ночью фиксит багу с ранним приходом SendInfoToPartner

це якщо є можливіть. Зовнішній платіжний гейт може смикнути callback endpoint з результатами платежу швидше, ніж покаже результат користувачу в браузер. А може й не швидше, тож обробляти треба і так і так. І пофіксити це ніяк не вийде, тільки підлаштуватися.

Єдріть я не заздрю тому місцю де ти зараз працюєш.

пишем цикл с time.Sleep()

бля дайте мені кнопку «дізлайк» негайно

Мене б ваші варіанти також не влаштували б. Це ж треба так оверінжінірити на рівному місці. У вас явно досвіду недостатньо, крутих книжок, статей і курсів начиталися, а ось як і що приміняти в реальному житті чуйки немає.

Я би спитав як часто таке відбувається що SendInfoToPartner викликається раніше ніж OrderCreated. Якщо рідко взагалі забив би на проблему.

Якщо частенько, я би поцікавився наскільки раніше приходить. Якщо хвилини, чи навіть секунди, я би робив як вони зробили тільки в пам’яті, без додаткових таблиць чи колонок.

Ну і як last resort вирішував би як вони.

Це якщо API мікросервісів на можна змінювати. А по хорошому, треба фіксити той мікросервіс який івенти шле, щоб слав в правильному порядку. Да і взагалі не має бути два 2 івента, мікросервіси трохи «по дебільному» задизайнені.

Да і взагалі не має бути два 2 івента

Та те що 2 івента то норм. Ордер створена і з ордером щось сталось це таки 2 різні події, це цілком легально.

А з іншими висновками погоджуюсь. Це елементарний кейс який легко фікситься в рантаймі.

на мою думку я б зробив щось схоже, тільки замість колонки в базі робив би кьюшку, так скейлиться краще імо. бо якщо запит sendInfo приходив двічі на один айді від двох партнерів — бінарне 1 чи 0 вже не зайде, треба складати інфу про партнерів. А це вже по означенню кюшка. Коротше, треба було питати більше питань про умови задачі. Але я б не пішов до них працювати, бо там де хамство = там мало платять

Можливо немає над партнерами контролю і там страшне легасі яке працює тільки так 🤷‍♂️ я таке бачив

взагалі кайфонув від спілкування з крутими професіоналами

Таких важко знайти.

Ну так, туди не треба йти бо там нема чого робити , тільки і усього. А загалом це справді ситуація коли співбесіду веде людина, яку скоріше за усе менеджмент видернув із з робочого процесу, може навіть під власну заміну. Звісно з того нічого путнього. На роботі справді інколи треба робити костиль, та звісно хизуватись їм на співбесіді — таке собі. Буває помилка коли робота треба, починати грати в гру такого співбесідника та намагатись відповідати під нього, а не так як треба. Тільки не треба так, просто ви на ту позицію не підходите.

В базі даних вони створили додаткову колонку/поле (не знаю що в них там), з ознакою того, що хендлер «SendInfoToPartner» туди приходив і не знайшов ордер — 1. Коли хендлер «OrderCreated» приходить писати ордер в цю табличку, він дивиться на це поле, і якщо там стоїть 1, то хендлер «OrderCreated» напряму викликає хендлер «SendInfoToPartner».

це взагалі то реалізація класичного бінарного semaphore для синхронізації потоків,
коли і інтерв’юеру і респонденту навіть не знайомий цей термін, то тут і додати більше нічого...

Семафор в якості колонки в базі o_O Ну це вже щось дуже новеньке. Взагалі OP подав розумну ідею, додати тріггер в базу, або створити третій сервіс якій збиратиме усе до купи та робитиме потрібну операцію. Додаткові колонки — безумовно костиляка.

А чому ні? класичне «вам шашечкі ілі єхать?»

Ну тобто питання на співбесіді. Є у нас технічна задача, от архітектурний варіант А, от варіант Б. Але обидва вони не вірні, вірно впровадити костиля. Про що і пише OP. До співбесіди просто треба готуватись в дві сторони, нажаль є такий тип менеджменту який працює без системно. Їм усе треба срочно бігом на позавчора, проект пішов команди ще нема та вона проходить співбесіду. Не встигаєм по строках — роздуваємо штат до 50 людей в одній команді. Про закон Брукса нічого чути не хочу і т.д. От ставлю гривню, чувачек, що вийшов на співбесіду дізнався про неї за 15 хвилин до неї, а в нього купа роботи і ще більше мітингів. З рештою — посиділки на ніч, бо з ранку на наступному клятому мітингу знову будуть питати — «Коли буде готово! Тут задача на три дні, пройшло пів години — де ?». Та що сука характерно, що такого менеджменту завжди є якісь замовлення та якась робота. От і розповсюджується токсичність.

Перепрошую. Свій комент я адресував тільки першому реченню, бо стало цікаво, чому колонка в базі (файл в директорії, квітка на підвіконні) не може бути (виконувати роль) семафора?
Все інше чисто вкусовщіна в межах наявної у нас інформації. Я би теж вибрав варіант з бд, якщо ми вже працюємо з бд. Хіба може не колонкою, а окремою таблицею, бо все одно доведеться десь зберігати результати сендТуПартнер. А городити черги без додаткових запитань не став би.

Вообще ОР начал городить свой велосипед, только с квадратными колесами.

Потому что первый вопрос, который надо было бы задать — это «как часто подобное случается?», «какая база уже используется?» и самое главное «Кто шлет эти запросы на ордера?»

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

А если таких случаев 1-2 в день из 10_000 ордеров — то решение с полем в табличке (хотя я бы вынес в отдельную табличку) вполне нормальное. А если таких ордеров 5_000 на потоке в 15_000 ордеров — тогде уже можно и рассуждать про кафку, триггеры, стримы и прочее. Только помнить при этом что все это тоже требует мониторинга и администрирования.

З іншого боку OP і запитали для того, щоб побачити його версію велосипеда. мірятися велосипедами — нормальна традиція велосипедоволодільців.

Ну там явно не про те. Чувака, що робив співбесіду батхертнуло з американського позітів майнду, де на співбесіді треба вихвалятись, зокрема казати, що пишаєшся усім, що зробив. Ну так по ельфіях так заведено. Усі насправді костиляють, при чому безбожно, у разі потреби, а деякі і завжди, бо бізнес є бізнес. Та казати так прямим текстом на офіційні зустрічі не прийнято. Ну тобто так, за Ілоном Маском — вчитись брехати, чого вже там.

Чому власне велосипед, ще і з квадратними колесами? Він надав два класичних шаблони з книги. Питання «якось криво влаштована система, давайте спростимо вимоги» теж не ставилось. Співбесіда це не робочий бізнес проект, де будьмо відвертими іноді треба робити архітектурні недоліки, йти на компроміси типу інтеграцій через iframe, щоб потрапити в строки та бюджет. В тому числі загажувати базу флагами та різним іншим мотлохом, після чого вона перестає нормально працювати в породі. Для початку треба взагалі потрапити на той прод. Про це і головне питання — нащо виносити робочу задачу на співбесіду ? Що ти хочеш перевірити, що людина здатна костильнути в разі потреби ?

Я хочу перевірити, як людина думає. Якщо хтось діє «отримав завдання і пішов ваяти архітектуру і педалити код» — це не сеньйор. Це міддл. Сеньйор для початку поставить уточнюючі питання, особливо якщо від відповідей на них залежить оптимальне рішення (*)

* Я зараз не про ОР

І що тут уточнювати ? Як зробити так щоб другий меседж приходив так як треба після саміту ордеру, а не до нього ? Чи чому тут взагалі два месаджи, або чому той сервіс який приймає ордери сам приймає не відсилає нотіфікацвї клієнту, чи не відсилає якись фулфіомент месадж і т.д. і т.п. утворюючи класичний чейн. Питання ставили конкретно — як вирішити от таку задачу — а ні як змінити задачу. Ви плутаєте сініорів з архітекторами, BA і т. д. Комусь звісно цікаво як і хто мислить, іншім цікаво обламати чувака на співбесіді, коли той почав з ним спілкуватись як з американьский замовником. Думаю, що людина йому в команду не підходить стало ясно миттєво, бо треба виконавець — а не розумник який гордиться своїми досягненнями або давно на минулій роботі займався тим що «продавав клієнтам рішення» і т.п.. Думаю дискусія якраз про це, про політику за великим рахунком. Є бувалі люди, які рекомендують коли шукаєш роботу ставити себе в положення цуценяти, який шукає родину. А не понти гнанти, є таке.

Додаткові колонки — безумовно костиляка

Якщо б мені платили по доллару кожен раз, коли зайва додаткова колонка допомогла вирішити проблему/баг та/або зекономила купу часу на зрозуміння, що таке незвичне сталося — то я б вже був доларовим мільйонером...

Тому більше колонок, хороших і різних :)

Це не розумна ідея. Це навіть не погана ідея, це ще гірше — це невірна ідея нахлобучена поверх іншої невірної ідеї

Це не розумна ідея. Це навіть не погана ідея, це ще гірше — це невірна ідея нахлобучена поверх іншої невірної ідеї

Так тут нема про мікросервісну архітектуру. Є сферичний модуль без привязки, який чомусь для солідності назвали «мікросервіс». А що як SendInfoToPartner 2 рази прийде до OrderCreated? Треба 2 рази відсилати чи це indempotent? Вигладяє як патерн медіатор для 2х подій. Тай усьо — без кафок.

ваше паттерн-фу дуже сильне :D

Без выяснения как работает их система и особенно не зная бизнес-требований невозможно решить эту задачу оптимально.

Зазвичай інтервювер і чекає щоб задавали питання, бо деколи по питаннях більш зрозуміло рівень людини ніж по відповідях.
А тут автор сходу "робим черед динамоДБ і лямди прикручуєм"=)

Враховуючи стиль подачі автора, я б теж очі закочував на його

Кажу, взагалі я пишаюсь всіма своїми розробками,

було заявлено, що компанія активно юзає AWS, звідси мої припущення про dynamo та ламбди. Як на мене, це логічно запропонувати утілізувати сервіси AWS.

Чи треба було в них спитати — а як ви ставитеся до того, щоб в файл писати ці флажки, як варіант?

Ну тут теж для заманухи. Зараз клієнт пішов любить їздити між : AWS, GCP та Azure. При чому по колу. Власне той самий Dynamo за великим рахунком можна запустити і просто як окремий POD, та при переїзді до GCP будеш переписувати усе на BigTable, робити міграцію данних тощо, що перекриє усі вигоди з дешевшої хмари. Тут само писали для Claud Spanner — перероблюй на Postgress бо клієнт вирішив на Azure переходити в т.д. в т.п.

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

Ну в общем то да. По нормальному есть скрипт собеседования, который как скрипт продаж. Собеседующий может спросить немного влево в право и т.д потом даёт фидбек. Собеседуют минимум двое ну и т.д. Когда какая то рабочая задача выноситься, это по сути не правильно с точки зрения собеседования. Но увы, «Маємо те — що маємо».

3 людини було.

При тому від інших були питання рівня «як протестити DateTime.Now в юнит-тестах» (.net)

BTW прикольне питання насправді.

Собесы не one to one обычно говорят о плохой организации в компании и неумении собеседовать.

Чому? Розкрийте думку.
З мого досвіда, якраз навпаки, але не завжди краще:
— 1 інтерв’юер. Велика вірогідність помилки. Процеси це якщо і закривають, то шляхом 2+ інтерв’ю — це витрати часу кандидата. Але найчастіше — це просто або набір лідом собі людей, або економія грошей.
— 3+ інтерв’юера. Зазвичай балаган, де взагалі нічого нікому не зрозуміло. Або, що краще для контори, але все одно не ефективно, 1-2 задають питання інші сидять і кивають. Як бонус може «злякати» недосвідченого кандидата. Може бути ефективним, якщо в компанії таки круто поставлені процеси, але таке рідкість.
— 2 інтерв’юера. Оптимальни сетап. Сильно зменшує вірогідність помилкової оцінки. Обидва інтерв’юера можуть задавати питання (і потім відповідати на питання кандидата). Кандидату все ще зручно тримати їх «в полі зору», тому співбесіда не перетворюється на балаган.

Велика вірогідність помилки.
Сильно зменшує вірогідність помилкової оцінки.

Подивитесь в словнику значення слова «вірогідність». Можливо, мали на увазі слово «імовірність»?

Собесы не one to one обычно говорят о плохой организации в компании и неумении собеседовать.

Та чого, це нормальна практика щоб інтервюверів було двоє — основний і другий номер (який ще
має мало досвіду інтерв’ю в цій компанії або позицією нижче)

Ну давайте поміркуємо швиденько
1. Тобто, подія з намальованої підсистеми, вихідна, з’являється тоді, коли є дві вхідні події.
Значить, підсистема повинна дочекатися появи двох вхідних подій. Тобто трігер формування і відсилання вихідної події — ми маємо 2 вхідні події.
2. Порядок вхідних подій — невідомий, відомо тільки що вони формують пару за чіткою ознакою.
Значить, нам треба зберігати вхідну подію. А під час збереження з’ясувати, чи не збережена пара? Як збережена, то можемо формувати вихідну подію. Як ні — то записати стан — «чекаємо другу».

Імплементація
Перше питання — з нуля чи «переставте один сірник на малюнку, щоб отримати ...»
З питання:

Оце — мікросервіс .... Як ви вирішете це?

можна припустити що другий варіант, реалізувати з мінімальним ускладненням.

З’ясовуємо — куди ми ВЖЕ записуємо вхідні події. Якщо записуємо тільки одну, а от зтикнулись з проблемою, то це і є те місце, де нам треба збирати оті пари вхідних подій для формування вихідної.
Якщо пишем ВЖЕ в двох місцях, то — сходу, недостатньо інформації для вибору. Залежить від властивостей цих двох сховищ, навантаження на них, розміру подій в байтах, емпіричного факту що все є частіше вхідна подія 1 фіксується раніше аніж подія 2

Якщо з нуля — то перше питання — а що вже використовує команда, в чому вже є експертиза?
другє — чи обрані продукти витримають навантаження, і інші вимоги тіпа PACELC

Ти загадив таблицю нерелевантними даними своєї інфраструктури. Цей «мікросервіс» взагалі не повинен існувати в цьому вигляді.

— Юначе, ми тут готуємо інженерів, а не математиків.
(з відомого анекдоту)

я бы просто переложил этот эвент в очередь, в начало. в зависимости от типа очереди. Если таймаутов и ре-сенд не предусмотрено.
Каждый человек решает по своему.

Я придумав своє гарне рішення. Після слів:

Дааа? Та що ви кажетеее!

Треба було зробити вигляд що отримали SMS. Далі робите великі очі, та ігноруючи інтервьюрера — вдаєте наче передзвонюєте (хто зна куди). Голосно питаєте — «Скільки, скільки ви пропонуєте? Це точна цифра?»
І виходите по англійські у цілковитій тиші.

DynamoDB? Лямбди? Redis? Чого не запропонували створити окремий кафка кластер під стріми, якийсь там Apache Flink? і вже по нормальному робити репартішин і джоїнити стріми.

Масштабніше треба, масштабніше, тай пятничний вкид має бути масштабніший

у чуваків норм костиль, заімплементили і пішли далі пиляти систему, а не обоардити щє одну платформенну хєрню і потім пояснювати інвесторам чому найняли щє одного dev-ops’a и чому кости на клауд виросли і потім через півроку лей-оффи і автор знову ходить по співбесідах

Якшо вже по феншую:
тут стандарний кейс з прекондішинами і стейт машиною, де замість окремого філда треба було робити ентіті яка відповідальна за «дьоргає якусь зовнішню апішку» яка щє й покриває аудит (включно результат виклику) і ретраї якшо зовнішня апішка просралась і тд і тп
Але то вже більш розширена версія їхнього костиля і мабуть у команди є більше пріорітетні таски ніж застрягати з комплексним рішенням на якійсь фігні.

Так запхали б усе в монолітну апішку+фронт сервер і не дрочили б нікому мізки, а то виходить на початку почали городити те, що ви на початку писали, а потім стейкхолдери прикрутили тестикули та кости на клауд і девопсів, от і городять тепер бог зна шо і щей на собісі вийожуються.

Так запхали б усе в монолітну апішку

Інтеграції з 3 сторонами — це зазвичай доцільне місце для винесення в окремий сервіс (гейтвей). Тому треба дивитись на конкретну ситуацію.

стандарний кейс з прекондішинами і стейт машиною, де замість окремого філда треба було робити ентіті яка відповідальна за «дьоргає якусь зовнішню апішку» яка щє й покриває аудит (включно результат виклику) і ретраї

бьютіфул заексплейніл, чьотко

Якась ху..ня, бачу тут івень і команду одночасно. Хто так робить?
Виглядає як системна проблема. Треба усі івенти одного об’єкта в один стрім складати і буде все добре.
А якщо треба хотфікс на рейс кондішен, то любий костиль ок буде.
Табличка з unknown orders виглядає ок. why not?

Ок, навіть якщо ми маємо два стріми з рейскондішен ми знаємо що sendinfotoparent повинен бути після ордер.
Тоді ми можемо синхронізувати іх на рівні транспорту, в залежності від message broker:
1. Якщо kafka — виконуємо pause і відбиваємо команду send (не комітемо partition offset) якщо order ще не створено, тим сами виникає ределівері. Або перекладаємо в топік ределівері
2. Якщо це звичайний message queue — відбиваємо окремий месседж і чекаємо ределівері. Або reschedule with delay

Затр***єте сервер рескедулами

як почув хамовате — «Дааа? Та що ви кажетеее!»...

Одного разу на обговоренні нового проекту мені не відповіли на моє привітання і почали відразу зі своїх питань. На цьому воно було і завершене. Я не розумію, чого ви там чекали після цієї фрази?

Це шо новий каргокульт ці мікросервіси ?
Раніше ібали мозги патернами, щас цими сервісами

Зараз патернами мікросервісів

Цьому тренду вже пару років

Трохи більше. Взагалі нічого дивного, коли деплоять на AWS читають книжки та доки — «Як проектувати для AWS» від техрайтерів Amazon і т.д. Це архітектура Amazon V6. Тобто результат 6 повної переробки системи Amazon, як я читав вона була впроваджена на сам інтернет магазин і платформу ще в 2007, коли власне придумали усю систему включно із самою девопсією та хмарою. Усі інші просто копіюють цю архітектуру, комбінують на її базі собі якісь рішення. Звичайнісінька комерція. Взагалі то тут нічого такого революційного SOA гетерогенні системи , та архітектури такого типу продумувались і використовуються дуже давно. Усі Саги, Оркестрації та Хореографії з брокерами сповіщень, виникли за довго до хмар та контейнерів з віртуальними серверами.

вже десяток років я б додав

Ну так чуваки що ніасілілі моноліт з паттернами, колхозять тепер мікросервіси в клаудах.

Я очень часто вижу как «микросервис» это жирнейший монолит, который еще умеет и скейлиться горизонтально с блокировками и внутренними скедулерами)

Чому в нього dirty а у вас — ні?

По факту ваш варіант при відсутності redis’a та dynabodb змушує їх ставити, налаштовувати і витрачати час на їх підтримку. А запропонований компанією можна зробити за 5хв і воно буде працювати так само як і ваш, тільки для бізнесу це буде дешевше

так мій теж dirty — це те, що я придумав на ходу за пару хвилин

А запропонований компанією можна зробити за 5хв

Зробити то можна, але не зрозуміти задачу і придумати костилі, тим більш знайти оптимальний костиль для заданого контексту

По факту ваш варіант при відсутності redis’a та dynabodb змушує їх ставити, налаштовувати і витрачати час на їх підтримку.

Там взагалі нічого невідомо що в них є, а щось явно має бути типу івентбаса і почнеш копати в цю сторону, бо мікросервіси ж.
Мабуть це по їх логікі має навести на думку, що костиль повинен бути тільки в контексті того що дають, тобто БД, але ж в реальному світі технологій на проекті куди більше і відповідно варіантів костилів і логічно що якщо даних ще немає, то треба якось підписатись на те коли вони з’являться, а база при наявності якогось асинхронного каналу зв’язку між сервісами точно не буде першим варіантом.

Знаєте як помітити що людина має психологічну патологію? Вона відмітає перший логічний варіант. Аля що спільного між снігом і паром? Відповідати замість того, що обидва — різні стани води, наприклад, що у обох є буква о. Так і ви думаєте, що є щось інше замість того щоб запропонувати очевидне рішення з тим що є, починаєте вигадувати що в них може бути. Під час інтерв’ю є можливість спитати, тому треба питати а не вигадувати. А так звичайно, у них може бути що завгодно і можна просто придумати що ми чекаємо що через деякий час воно знову до нас прийде, тому що ми так придумали

ту мач для фікса одного юзкейса, занадто комплексно

тому краще взяти не підходящі під задачу технології і думати як вирішити проблему цим породжену. Best engineering practices in action

А чого не можна створювати івент після запису у базу? Сервіс котрий кладе джейсон в базу потім генерує івент для СендІфноФорПартнер. Все одно це івент без запису у базі не має сенсу.

Я так зрозумів що івент приходить з іншого місця з айді, якого ще немає в базі

А чого не можна створювати івент після запису у базу?

Бо запис в базу і відсилка івенту нетранзакційні

Але і рішення запропоноване компанією нетранзакційне.

Легко може бути транзакційним, якщо обидва хендлери складають данні в одну базу наприклад. Цих деталей не має у варіанті компанії.

Питання як раз і було чому вони нетранзакційні? І як зробити їх транзакціними.

Підписатись на коментарі