TGViewer
Channel Public Channel
Мамкін Архітектор

Мамкін Архітектор

@mamkin_architect

Для звʼязку пишіть @ska_9000
Канал про айтішечку, автор якого трохи пожив життя і може пояснити за бекенд, веб, мобайл, автоматизацію, клауди або як раніше було краще.
Subscribers
3.24K
Photos
154
Videos
4
Links
369
Recent Posts 20 shown
Post #704 1.13K
Хтось не деплоїть по пʼятницях.

Ми не деплоїмо, поки триває тривога.

Ми різні
  • ❤ 40
  • 👍 5
  • 🔥 3
  • 😱 2
  • 🫡 2
  • ⚡ 1
Post #703 1.33K
Оновив Portainer однією кнопкою

Я вже не раз розповідав, як влаштований мій homelab: є сервер на Umbrel, на ньому Portainer, а в Portainer крутяться мої саморобні сервіси, Bankoscan, Дрони на районі і тд.

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

Оновити його просто, бо в мене ж Umbrel (якщо не знали, це такий user-friendly Linux, який має свій App Store, де застосунки встановлюють і оновлюють кнопкою).

Зайшов на Umbrel, дійсно є пропозиція оновитись, тицьнув кнопку, а далі як в анекдоті: "сиджу, колупаюсь цвяхом у вусі, і раптом бац — звук пропав".

Umbrel перестав відкриватись, а в Telegram посипались алерти: відвалився сам Umbrel, GitLab, Grafana і ще кілька сервісів. При цьому Дрони на районі спокійно працювали далі, що було дуже добре, бо якраз була тривога. Оновлюватись я все одно хочу постійно, просто інфру, мабуть, краще чіпати в тихі години, і заодно зробити її такою, шоб апдейт однією кнопкою не клав половину homelab.

Почав розбиратись, і знову проблеми з Tailscale. Старі хости в tailnet перестали відповідати, натомість зареєструвались нові з тим самим іменем, тільки з -1 в кінці.

Виявилось, шо Umbrel запускає Portainer як docker-in-docker, і оновлення застосунку просто перестворює цей контейнер. Переживає таке тільки його /data, а мої стеки тримали свій state поруч, у /home/umbrel/homelab-data, звідки його знесло. Tailscale-ноди забули, хто вони, а Prometheus втратив усю базу, 130к метрик (про це алертів не було).

Розгрібали це з агентом приблизно годину (сам я б залип на пару днів точно). Дані стеків переїхали під /data, шоб наступне оновлення їх не чіпало, а Prometheus тепер щоночі бекапиться на TrueNAS і алертить, якщо база раптом обнулилась.

Прикольно, шо самі образи, як і дашборди Grafana, при цьому нікуди не ділись, схоже, бо лежали якраз у /data. Але осадочок, як кажуть, лишився.

Чому це сталось? Бо для моїх потреб ванільного Umbrel недостатньо. Мої смаки доволі специфічні, і не налазять на opinionated конфіг Umbrel, насамперед на конфігурацію Tailscale. Тому коли шось оновлюється, дефолти перезатираються і перед очами постає мем "oh shit here we go again".

Схожа історія в мене була з TrueNAS, де також є можливість "просто" ставити апки. Там одна з них посередині апдейту розгубилась і в результаті не можна було ні відкотити, ні накатити. Я декілька разів пробував це полагодити з консолі, і все безрезультатно. Аж поки не натравив туди Claude Code, який за 5 хвилин підняв усе.

Тож з Umbrel, схоже, треба валити. Поставити собі якогось Debian, і горя не знати. Бо головна перевага Umbrel — його простота і UIшність — для мене не працює: все там я роблю через ssh, та і не я роблю, а агент.

З вас лайк та історія, як у вас апдейт однією кнопкою поклав прод 🙂 Або порадьте, шо можна взяти замість Umbrel (його оновлення, якщо шо, досі висить)
  • 👍 32
  • ❤ 2
  • 😁 2
Post #702 2.15K
Обіцяв технічні подробиці по Дронам на районі, тому ось вони.

Стек частково вже називав: Python, htmx, трохи JavaScript для інтерактиву. Service worker, щоб сайт відкривався в офлайні і сам казав, що карта вже неактуальна. Cloudflare тримає тунель, захист від ботів і CDN.

Google Analytics стоїть, щоб бачити, чим люди реально користуються, і з цього вирішувати, що робити далі.

Deployment максимально дурний: Docker Compose збирає образ прямо під час деплою, без зовнішнього registry. Крутиться воно в Portainer, який живе в Umbrel на домашньому сервері і раз на хвилину підтягує main. Gitlab також на Umbrel.

Спочатку я хотів винести це на безкоштовну віртуалку в GCP, щоб не залежати від домашнього світла, але там portainer-агент не вміє проксювати BuildKit, і збірка падає з http2: frame too large. Переніс додому, шоб швидше вийти в прод.

Моніторинг — Prometheus і Grafana, які й так підняті в моєму homelab, плюс Uptime Kuma, щоб знати, що сайт взагалі відповідає.

Проте найгірша поломка тут не "сайт впав", а "сайт віддає 200, а дані в ньому тригодинної давнини". Жоден зовнішній пробник такого не побачить, тому окремою метрикою я віддаю вік останнього успішного забору по кожному джерелу, і алерт висить саме на ній.

Всередині немає ніяких AI- чи ML-тулів, там набір if-ів, регекспів і маленька state machine. Працює доволі непогано.

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

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

Тестується все агентом, який запускає playwright-cli. Ним же і перевіряє баги. Також є юніт тести, зараз десь 500, http залежності тестуються через vcr.

А і мало не забув — Redis тут немає, натомість SQLite, бо з ним банально швидше вайбкодити. Файл лежить поруч з процесом, схема міняється на льоту, нічого не треба підіймати окремим контейнером і потім за ним доглядати. По перфомансу питань нема взагалі.

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

Пишіть в коменти ідеї, зауваження і побажання. Також попрошу пошарити серед друзів, сусідів і колег.
Дрони на районі Дрони на районі: тривога, дрони і ракети поруч із вами Тривога, дрони і ракети у вашому районі Києва і області за даними Telegram-каналів. Наживо, без реєстрації.
  • 👍 40
  • 🔥 10
  • ❤ 5
  • ❤‍🔥 1
Post #701 2.09K
‼️ увага ‼️ Я провтикав і випадково закрив коменти деяким підписникам пару днів назад.

Зараз це виправлено. Якщо вам писало, що вас забанено в групі, спробуйте зараз.
У випадку проблем пишіть мені в особисті.

Дуже вибачаюсь, це все незаплановано

Шо насправді сталось:
Система коментарів в телеграмі працює через окрему групу. Пости і коментарі попадають в ту групу, коментарі пишуться, як відповідь на пости і показуються під постами на каналі. Деякі підписники додаються в ту групу і починають писати коменти прямо в ній. Але повідомлення, які просто там написані, не попадають в коменти на каналі (бо вони не цитують пост). Виникає плутанина, і хтось може відчути себе проігнорованим.

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

Рішення було повидаляти людей зі списку видалені. Тепер все має працювати.

Якщо ви знаєте когось, хто образився через цей бан, розкажіть їм пліз. Хай повертаються :)

Ну і принагідно нагадаю, що для спілкування є чат, посилання в закріпленому повідомленні.
  • ❤ 5
  • 😁 3
  • 🔥 1
Post #700 2.66K
В Києві останнім часом тривога триває постійно, з дуже короткими перервами.

Раніше треба було знати одне: є тривога чи нема. Зараз питання інше: що конкретно ця тривога означає для тебе. Де летить, що летить і чи летить воно до тебе.

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

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

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

Сайт на Python і HTMX. Ідея була використати мінімум JavaScript, але затягнути його все ж довелось. Service worker, щоб сайт працював в офлайні і показував, що дані неактуальні. Плюс схематична мапа, без клієнтського коду вона не працює. Ставку зробив на серверну генерацію контенту, і HTMX з цим справляється чудово.

Задеплоєно на моєму домашньому сервері, тому самому, що на балконі. Поки є електрика, він буде там. Коли почнуться проблеми з доступністю, можна буде перенести кудись у датацентр.

Оскільки воно працює локально, питання економії ресурсів стоїть доволі актуально.

Тому сайт закритий за Cloudflare. Безкоштовного плану вистачає, щоб підняти тунель і налаштувати CDN та кешування. Завдяки кешу значна частина запитів до самого сервера не долітає.

Щоб сторінка оновлювалась сама, спочатку взяв WebSocket. Потім згадав, що є server-sent events, які більш оптимальні для односторонньої комунікації. Але є проблема — кожен клієнт це окреме зʼєднання. І коли їх багато, то це дефіцит ресурсів. Тому перейшов на звичайний polling, коли клієнт робить періодичні запити за таймером. Тоді вся робота перекладається на клієнтів, і в поєднанні з кешем на Cloudflare частина тих запитів до мого сервера не доходить зовсім.

Кешування стоїть на 20 секунд. Розрахунок був такий: навіть якщо туди ломануться 10-20 тисяч людей і будуть регулярно оновлювати, до мене дійде приблизно один запит за ті 20 секунд на кожен фрагмент, тобто на район, на мапу, на сторінку.

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

Споживання ресурсів: 162 мегабайти памʼяті з дозволених 512 і біля 2% одного ядра. Пік, який я зловив, 47 відсотків, то було на якомусь шальному рендері мапи. Тобто місце для росту є.

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

Напишіть у коменти, що не працює або чого там не вистачає. Мені зараз найцінніше саме це. Ну або поставте лайкос — це теж дуже в тему :)
Дрони на районі Дрони на районі: тривога, дрони і ракети поруч із вами Тривога, дрони і ракети у вашому районі Києва і області за даними Telegram-каналів. Наживо, без реєстрації.
  • 🔥 75
  • 👍 25
  • ❤ 8
Post #699 2.81K
Від умовного Скайнету чи Матриці нас рятувало те, що LLM-ки доволі повільні: довго відповідають на питання, довго приймають рішення.

Проте нещодавно вийшла нова модель (чи як її правильно назвати, бо самі автори кажуть System One model), яка цю проблему вирішила.

Називається Jev, від TypeSafe AI. Це штука, яка дозволяє вирішувати певний ряд питань за мілісекунди там, де LLM може витрачати секунди, а то й хвилини.

Йдеться про класифікацію. Ця модель дуже швидко і дешево видає відповіді на три типи питань. Перше — до якої категорії відноситься певне твердження. Друге — відповідь «так» чи «ні». Третє — оцінка за шкалою, яку ти сам описав, типу «наскільки серйозний цей баг, від 0 до 2». І до кожної відповіді йде ймовірність, наскільки вона в ній впевнена.

І тепер є змога ті місця, де LLM підтуплювали і довго чекали, замінити рішенням, яке дає приблизно той самий результат за мілісекунди (обіцяють 70–500 мс) і за дуже дешево: 4 центи за мільйон вхідних токенів, а вихідні взагалі безкоштовні.

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

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

І ось воно вже є і ним можна користуватись. Зараз вже є готові скіли для Claude Code, які дають агенту контекст про Jev. Або просто кинути йому доку і попросити самого переробити свій workflow.

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

Взагалі, мені здається, це перша така епічна річ з часів анонсу ChatGPT, хіба шо ви нагадаєте щось інше, бо пам'ять вже не та. Ну і напишіть в коментах, шо у вас з Jev вже вийшло (на крайняк поставте лайк).
  • 👍 48
  • ❤ 5
  • 🔥 4
  • 🤡 1
Post #698 2.47K
Полагодив Tailscale через Tailscale

Я вже писав (буквально в минулому пості), шо в мене вдома стоїть окремий старий макбук, на якому 24/7 крутяться агенти, а я заходжу туди по SSH і вебу звідки завгодно. Схема доволі зручна, бо робочий ноут можна закрити, забути вдома чи залити кавою (боже збав), а робота йде далі сама.

Але ось на днях, коли я був не вдома, ноут перестав виходити на зв'язок. Підключаюсь, таймаут, пробую ще раз, знову таймаут. При цьому Hermes, який на ньому живе, бадьоренько відписує в Telegram, шо все добре, тільки він чомусь перезавантажився. Ну, це вже щось.

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

Добре, шо в tailnet у мене є ще пара машин, і серед них Umbrel. Далі я зробив те саме, шо і під час минулого outage: відкрив Claude Code і написав йому "ось Umbrel, зайди туди, знайди в локалці макбук і пофікси. make no mistakes". Він зайшов, знайшов, побачив, шо Tailscale лежить, підняв його, і все знову працює. Деталі тут мабуть неважливі, звісно це можна зробити самому руками, але нашо.

І чого ж має навчити нас ця історія?

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

Друге, заходити на один хост через інший можна прямо з одного компа, не відкриваючи термінал на проміжній машині і звідти ще один. Хост, через який заходиш, називається bastion, і в SSH для нього є вбудований прапорець: ssh -J user@bastion user@target. Я так роблю час від часу з іншими мережами. Робиш бастіон, додаєш собі в tailnet і потім через ньогоходиш.

Третє, макбук як сервер має певні обмеження. Tailscale на macOS піднімається лише разом з юзером. Автологін теоретично є, але увімкнути не можна коли диск зашифрований. Плюс періодично вилазять дозволи на запуск, наприклад, коли оновлюєш шось через brew, то вилазить в UI вікно, а в ssh все просто підвисає. Це вирішується через Screen Sharing (який працює через той самий tailscale), але додає фрікшена.

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

І поки я тут розповідаю про Tailscale, пан Сіпласпластик написав про фішку Tailscale, про яку я не чув. Дуже раджу почитати, ось посилання: пост про tailcat.
  • 👍 11
  • ❤ 9
  • 🔥 3
Post #697 2.45K
Шість годин компіляції заради одного апдейту

В мене загудів макбук. Той, шо "стаціонарний", на якому 24/7 токени агентів перетворюються у value. Він хоч і на Intel, але гудить доволі рідко, навіть коли всередині крутиться з десяток сесій з агентами, тому я поліз у top глянути, шо там. А там cmake, ninja, десяток clang++ і rustc. Перша думка: "блін, знову хтось щось переписав на rust".

Все, шо я зробив перед тим, це запустив оновлення aoe, мій новий краш із серії "tmux для агентів". Оновлення запускається через brew, який вже мабуть з місяць кожного разу шось гундить про те, що треба оновити Xcode до 26 версії. Проблема в тому, що для цього треба оновлювати саму macOS, але на інтелах це оновлення недоступне.

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

Гуділо воно шість з чимось годин. Я сидів, дивився в top, писав про це в твіттер і вже зі спортивного інтересу не переривав.

Потім розібрав логи в ~/Library/Logs/Homebrew, і виявилось, шо всі ті години пройшли не дарма. Позбиралась ціла купа цікавих речей: llvm, node, rust, ну і сам aoe. Причому llvm зібрався аж двічі (дві різні мажорні версії), і кожна збірка займала 100+ хвилин. Дякую за це, відчув себе бородатим програмістом, який збирає під себе кернел та інструменти з сорсів, але нашо воно мені, коли можна скачати?

Виявилось, що у вересні Homebrew перевів Intel-маки в Tier 3. В двох словах це значить, що нове все буде не качатись, бо готових bottles нема, а збиратись.

Шо це за тіри в Homebrew я не знав, але ось дізнався проти своєї волі. Це типу рівні підтримки, Intel там уже на передостанньому, а у вересні 2027 його прибирають зовсім. Нормальна залізяка (i7, 16 гігів, 500 SSD, тоненька і гарна) отримує пенсійне посвідчення і пропозицію піти нахрін. (лайкніть, якщо у вас теж ще Intel)

Побічний ефект — я краще зрозумів мем про Compiling. Трохи стало шкода C розробників, у пітоністів таких проблем нема 🙂 Сам мем у коментах, якщо ви його не бачили.

Міняти макбук я не буду, бо є M1, і питання скоріше в тому, чи міняти вже M1. А цей, мабуть, поїде на Omarchy. Але не сьогодні, бо в мене ще агентам треба роботу доробити.
  • 👍 18
  • ❤ 14
  • 🤔 3
  • 🔥 1
  • 😁 1
  • 🤝 1
Post #696 2.37K
Хто моніторить монітор?

Вчора вечором мені в Telegram поприлітало кілька червоних алертів: хост, на якому крутиться Uptime Kuma, не відповідає. Я писав раніше, шо поставив її для моніторингу своїх ресурсів, а потім додав ще моніторинг самої Kuma, на випадок, якщо впаде вона. І цей час настав 🙂

Спробував зайти на неї — не відповідає. Схоже, що віртуалка лежить. Дивлюсь в імейли, які я пропустив, а там urgent alert, що мій акаунт видалився:

> Your billing account has been terminated for failure to provide a valid payment instrument or for not making all overdue payments. In addition the related Project(s) and/or Service(s) have been terminated.

Так би я, мабуть, забив на це до ранку, чи навіть понеділка, але фраза "account terminated" мене (неприємно) тригернула, і я поліз дивитись, шо там відбувається.

Виявилось, шо картка була прострочена, гугл не зміг списати гроші, обурився і вирішив не працювати. І видалили не сам акаунт, а біллінг-акаунт (так, в листі це і написано, але після слова terminated далі якось не читається). Його можна було відновити, якщо оновити картку, і потім просто пододавати до нього мої проєкти. Тобто все було набагато прозаїчніше: оновив payment method, понажимав кілька кнопочок, і все повернулось назад. В інших клаудах це все обходиться без драми, чи може я давно не попадав в таку ситуацію.

Висновки, якими хочу поділитись.

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

По-друге, комунікація від Google. Не знаю, чи вони це спеціально придумали, чи так випадково получилось, але слова "account terminated" додають +67 до мотивації негайно розбиратись. Якщо це by intention, то моя повага.

Ну і третє: сума, через яку весь цей двіж виник, — 62 центи. Можливо, навіть не на тому проєкті, бо там ще є якісь тестові, які я колись створював, десь якісь ресурси висять і їдять копійки, і може воно це все і тригернуло.

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

Кидайте в коменти найменшу суму, через яку у вас падав прод. Мої 62 центи, мабуть, не рекорд.
  • 👍 18
  • 😁 8
  • ❤ 4
  • 🔥 2
Post #695 2.3K
Програма, яка друкує сама себе

Вчора подивився ролик, який починається з quine — програми, яка виводить власний текст. І згадав давній осадочек.

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

Писав я тоді на Basic (не Visual, а звичайному, з номерами рядків і goto), потім на Pascal. На умовному Python чи JavaScript, де є eval, це робиться доволі просто. А в олдскульних мовах — нєа, ніяк. Завжди питання, як вивести той самий print() верхнього рівня.

Тому перше, шо я подумав після ролика: а чи зможе АІшка? Виявилось, може. І на Pascal, і на Basic. Не з першого разу, кілька ітерацій, але в результаті — текст, який друкує сам себе. Сюди його не вставлятиму, самі можете перевірити 🙂

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

Але я почав про відос. Там через самокопіювальні програми і віруси сюжет якось дійшов до Game of Life. Завдяки йому я дізнався, шо Life виросла з питання фон Неймана ще з 40-х: який мінімальний набір інструкцій потрібен машині, щоб зібрати робочу копію самої себе.

Фон Нейман придумав під це клітинний автомат на 29 станів і десь 200 тисяч клітин. А Конвей у 1970 поцікавився, наскільки простіші можуть бути правила. Так і вийшла Game of Life.

До речі, реалізувати Game of Life теж така собі історія. Спочатку проста: правила на скінченному полі пишуться за вечір. Проте якщо додати, шо поле нескінченне, а зум можна крутити як завгодно, стає трохи веселіше.

А саме це і треба, щоб зібрати Game of Life всередині Game of Life. В ролику це з 5:57 до 6:23, без слів, просто зум. Подивіться, воно того варте.

Розкажіть в коментах, чи пробували ви таке написати. І лайк, якщо у вас теж не вийшло (так, лайків хочу більше) 🙂
  • ❤ 12
  • 👍 9
  • 🔥 5
Post #694 2.1K
SQL зроблено для людей

Уважні читачі під минулим постом трошки напхали зауважили, що нормальні форми — це не про storage, а про цілісність даних. І обурились, що не було ні слова про сам SQL як мову.

Довелось гуглити. Кодд (той дядько, який придумав реляційну модель) у 1971 назвав чотири цілі нормалізації, і економії місця серед них нема. Там радше мова про зменшення кількості апдейтів під час операцій: менше дублів, менше операцій писання, кожна з яких займає час і може впасти. А от цілісність, якщо читати між рядків, серед цілей є.

Цілісність даних — це добре. Проте з ростом навантаження і скейлінгом цілісність починає бути проблемою. Власне, проблема не в цілісності. Проблема в механізмах для її забезпечення, зокрема foreign keys, які постійно перевіряють наявність записів під час вставки і гальмують систему.

Але насправді foreign keys потрібні лише за умови, коли з базою працюють люди вручну. Люди пишуть SQL команди вручну, десь помиляються, а база підстраховує.

Коли ж з базою працюють виключно застосунки, то вони і забезпечують цілісність. Дуже важко уявити собі ситуацію, коли у вас на продакшені стрельне foreign key violation, і це буде нормально. Насправді це означає, що у вас бага в коді або гонка між двома писунами (writers), що теж бага, і її треба фіксити. І виходить, що більшість перевірок працюють вхолосту в майже 100% і тупо уповільнюють систему. Саме тому серед порад "як пришвидшити роботу бази" трапляється "приберіть foreign keys". У GitHub їх не використовують взагалі, бо заважають шардити, у Shopify тільки на рівні коду.

Ще був комент, що для фінансових проєктів треба саме SQL, бо там транзакції. Але ж в реальному світі ACID майже ніде немає. Операція на кількох учасників майже ніколи не атомарна. Ти дістав гроші, віддав касиру, і раптом потухло світло чи вбіг грабіжник. Між моментом, коли ти віддав гроші, і моментом, коли вони з'явились на рахунку, проходить час. І в цей час може статися так, що і грошей у тебе вже нема, і на рахунку нічого не з'явилось. А потім це все треба якось вирішувати.

Банки з'явились задовго до комп'ютерів і якось працювали: папірці, пошта, процеси підтвердження, механізми компенсації. Гроші нікуди не зникали. Ті самі саги і компенсації, тільки на папері.

І десь під 2010, вся NoSQL двіжуха, а потім і мікросервіси, почала це впроваджувати: eventual consistency, сагі, компенсації. Виявляється, вони теж дають гарантії, яких достатньо для бізнес-процесів. Разом з тим NoSQL дозволяв простіше закривати проблемні місця реляційних баз: шардинг, міграції схеми на великій таблиці, масштабування запису, а не тільки читання.

Тепер про SQL як мову. Її придумано для людей, щоб їм було зручно працювати. І вона фантастична. Це один із перших декларативних підходів ( Prolog був ще раніше, якщо шо), коли ти кажеш, що тобі треба зробити, а як, вже вирішує база. Я не применшую її чеснот, і використовую її постійно. Мені простіше написати запит на SQL, аби поджойнити CSV файли, ніж згадувати аргументи методів pandas, наприклад.

А от коли з базою працюють програми, то все стає навпаки. Їм воно незручно. Передача параметрів, захист від SQL injection, query builders, ORM. Це все понапридумували в тому числі для того, аби інструмент під людей (SQL мова) підігнати під програми. Бо їм треба інші речі: структуровані API замість тексту.

Ну от, з коментарями розібрались (хоча завжди раді новим, наприклад — чому FK не можна просто взяти і прибрати). А в наступному пості перейдемо, власне, до баз, які мене вразили: це, звісно, Redis і DynamoDB.
  • ❤ 22
  • 🔥 8
Post #693 2.1K
Це буде серія постів про мій досвід з базами даних, або чому мені подобається Redis. Почати хочу, власне, спочатку.

Ще в школі я читав комп'ютерні журнали, і там писали про бази даних. Для мене це було щось складне. База даних. Ого! Там були назви FoxPro, Clipper: настольні бази (доволі примітивні насправді), проте таблиці, індекси, запити мене вражали. А потім це вже став сервер, ти підключаєшся до сервера, і це звучало дуже потужно.

На моїй першій роботі ми масово використовували MS SQL, і на то були свої причини. Одна з них та, що тоді, мабуть, нічого іншого особливо і не було. Реляційні бази — це був way to go, industry стандарт без якихось альтернатив. Та й зараз, коли хтось каже "база даних", у більшості людей в голові буде SQL.

Ну, ви знаєте: нормальні форми, relations, кортежі (шо це?), SQL, ось це все. Думаю, що нормальні форми — це штука, обумовлена обмеженнями тогочасних технологій, тому що storage був доволі дорогим, і треба було думати, як зберігати інформацію ефективно. До речі, я б мабуть не пройшов співбесіду, якби треба було пояснити різницю між третьою та другою нормальною формою, але пам'ятаю, як упарювався, доводячи кастомеру, що дублювати одне поле в двох таблицях не можна, і треба робити третю куди це виносити 🙂

І якщо обрати топ-один причину, чому реляційна база стрельнула, то, мабуть, це саме storage. Інша причина, можливо, в тому, що таблиці в головах людей були дуже схожі на те, з чим вони працювали на папері. На папері ти малюєш таблички, ось тобі таблички в компутері. Спредшити, Excel, а до того Lotus 1-2-3. Метафора з паперу перейшла в застосунки, а потім на сервер (чи спочатку на сервер, якщо згадати мейнфрейми).

Ми писали проги на Delphi, і щоб оновити програму, треба було піти на сервак, скопіювати її на шару, а перед цим прослідкувати, щоб всі люди з неї повиходили, бо файл тримався Windows-сервером. А stored procedure ти просто міняв, і одразу вся логіка застосовувалась у всіх, хто її використовував. Тому не дивно, що ми доволі широко використовували SQL для зберігання бізнес-логіки.

Можна подумати, що я хейтер SQL і насправді його не знаю, а просто хочу будь-що, аби не SQL. Але насправді ніт. Я робив на ньому дуже складні речі, саме на Transact SQL, які, можливо, не варто було б робити на ньому. Працював з тригерами, з транзакціями. Єдине, чого не робив: процедури, які викликають процедури, бо це навіть для мене здавалось занадто. Але працював з кодом, який це використовував, і свого часу вважав себе дійсно експертом. Тому ні, SQL я знаю нормально і вважаю, що можу його критикувати і шукати щось інше.

Проте з часом воно трошки приїдається, настає криза формошльопа, який хоче жити інтересно і бути шпіоном, як казав класик. І тут на сцену виходить NoSQL, але про це буде наступний пост.

Напишіть шо ви думаєте за SQL — норм чи стрьом?
  • ❤ 21
  • 👍 19
  • 🔥 7
  • 🥱 1
Post #692 2.36K
Реверснули сигналізацію заради Home Assistant

У мене вдома звичайна GSM-сигналізація. Не Ajax і не якась модна історія, простий пульт від постачальника послуг. Керується через хмару: є застосунок, ставиш і знімаєш з охорони. Проблема в тому, шо той застосунок треба щоразу відкривати, або вводити код на панелі, де клавіатура час від часу підзаліпає.

Захотілось, щоб воно саме ставилось, коли всі вийшли з хати, і само знімалось, коли хтось зайшов.

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

Грошей шкода, а вдома вже стоїть Home Assistant і поряд Claude Code з токенами. Ну то чом би не спробувати.

Перше, шо зробили: завернули трафік застосунку через проксі, подивитись, як воно говорить з хмарою. В мене openwrt на роутері, агент поставив туди якусь приблуду і побачив весь трафік.

І тут перший сюрприз: усе їде по звичайному HTTP, без TLS. Тобто трафік керування охоронною системою читається в тій самій мережі голими руками. Для охоронного продукту це трохи занадто відкрито, але я не шарю — може всі так роблять 🙂

Тіло самої команди все ж було зашифроване, тому дістали APK і декомпілювали. На Android майже все на Java, тому це доволі просто: розбираєш dex і читаєш логіку. Всередині знайшовся ГОСТ 28147-89 (це стандарт шифрування) з нестандартними S-box (це таблиці заміни: шифр підставляє одні значення замість інших), захардкодженими прямо в застосунку.

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

Відтворили шифр, креди знаємо, скрафтили команду на постановку, відправили. Хмара відповідає OK, але панель мовчить і нічого не робить. Payload валідний, дешифрується коректно, помилки ніде немає. Тут би я здався, але агенти не здаються.

Розгадка знайшлась, коли почали звіряти свій трафік і живий трафік застосунку. Виявилось, шо команда це не один запит, а два: спершу ping за одноразовим токеном сесії (він живе хвилин десять), і вже той токен треба покласти в наступний запит. А байти, куди запихали ідентифікатор панелі, насправді чекали на токен. Обидва варіанти дешифруються однаково валідно, тому вгадати наперед було неможливо.

Ще був код активації, з якого робиться ключ: у відкритому вигляді він не передається. Довелось брутфорсити його з перехопленого запиту, відсіюючи варіанти по контрольній сумі. Кілька хвилин, і ключ підібрано. Дуже добре, що він виявився коротким і M1 навіть не напрягся.

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

В цілому воно зараз працює. Панель під'єднана до Home Assistant, ставлю і знімаю з телефона, приходять нотифікації про втрату живлення і тд.

Але прикол в тому, що тепер я повернувся туди, з чого починав. Інтеграція є, а от як її безпечно автоматизувати — досі питання. Думав ловити телефон у домашній Wi-Fi і по цьому знімати охорону. Але телефон може сісти, Wi-Fi глюкнути, а ціна помилки тут не просто "ой": приїде наряд, і далі ти пояснюєш людям з табельною зброєю, шо тривога хибна.

Тому автоматику поки поставив на паузу. Шукаю гарні варіанти, щоб було просто і безпечно. Може ви знаєте? Напишіть в коменти.
  • 👍 28
  • ❤ 9
  • 🔥 2
Post #691 2.93K
https://opusfived.dev Якщо у вас закінчились токени, але ви не можете без спілкування з ШІ, ось вам сайт.

Ті ж самі емоції, безкоштовно
  • 😁 24
  • 🔥 20
  • 🤣 6
  • 👨‍💻 3
  • 👀 2
  • 🤯 1
  • 🥱 1
Post #690 3.07K
це вже AGI?
  • 😁 51
  • 👍 32
  • ❤ 3
Post #689 2.83K
Подивився відео, де чувак зробив гру повністю на функції синус. Не "переважно", а буквально всю: графіка малюється синусами, звуки синус, музика синус, шрифти синус, побудова ігрового світу теж синус. Асетів немає взагалі, все рахується з однієї функції.

І мені це прямо дуже сподобалось.

На фоні того, скільки зараз генерується AI-слопу і generic контенту, який нічим не відрізняється від сусіднього каналу, таке відео стало рідкістю. Гарно зроблено, гарно розказано, і по дорозі можна підтягнути матчастину: перетворення Фур'є і як воно все працює докупи.

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

А далі мене понесло в спогади.

Бо це той самий жанр челенджу, коли щось робиться одним-єдиним типом інструменту. В іграх це, наприклад, обіграти грандмастерів у StarCraft одним типом юніта. Грандмастер це найвищий ранг у змагальному сегменті, тобто там суперники, які і без жодних обмежень тебе розберуть. Обмеження вигадане, користі з нього нуль, а затягує.

І я згадав, як в школі читав книжку про програмування. Вона була про структурне програмування — зараз цього, мабуть, уже ніхто не пам'ятає, бо на якомусь етапі структурне програмування замінилось модною молодьожною парадигмою під назвою ООП.

Там на прикладі Pascal і Basic показувався набір структур коду, з яких складались тогочасні програми. Конструкції ті самі, якими ми користуємось і зараз: if, if else, while, until, case, goto і тд.

А в кінці була теза, що всі їх можна замінити одним циклом while. Читабельність при цьому втрачається повністю, але якщо стоїть така мета, то можна.

Книжка була російською, і назви там були свої: if називався "альтернатива", until "цикл до", а while "цикл Пока". Останній я спочатку прочитав з наголосом на першому складі і був певен, що Пок — це якийсь чувак, який його придумав, як Дейкстра чи Бекус.

Ось такі рандомні думки з одного відео.

Напишіть в коменти, якщо у вас теж траплялись випадки, де задача вирішувалась звуженим асортиментом засобів. Ну і лайк поставте :)
  • 👍 47
  • ❤ 9
  • 😁 7
  • 🔥 5
Post #688 2.49K
#реклама

🤖 AI вже давно не просто чат-бот. Сьогодні від AI-інженера очікують уміння перетворити модель на повноцінну production-систему. Але як побудувати надійний AI pipeline?

Навчіться працювати з RAG та агентами, контролювати якість, latency і cost, захищати систему та масштабувати її, — на курсі «AI Engineering» від robot_dreams.

Протягом 18 занять ви:
🤖 інтегруватимете LLM через API та self-hosted рішення й працюватимете з prompt engineering
🤖 будуватимете RAG-системи — від ingestion та embeddings до retrieval і reranking
🤖 створюватимете AI-агентів, працюватимете з tool calling, Agentic RAG та MCP
🤖 проєктуватимете production-архітектуру з API, caching, guardrails та observability

За час курсу створите повноцінний AI-продукт — від інтеграції моделі до production-архітектури — і додасте готовий проєкт у портфоліо.

Лектор: Андрій Білоус — AI Solution Architect у ZONE3000, має понад 12 років досвіду в IT та 5+ років у Fullstack та AI-розробці.

Деталі, програма та реєстрація ⬅️
  • 🥱 9
  • ❤ 4
  • 👍 2
  • 🤡 2
Post #687 2.86K
Сидів у сесії з агентом, крутили UI, і він нагенерував пачку скріншотів: ось дивись, яке гарне. А як я подивлюсь, коли сиджу по ssh і в мене там термінал і більше нічого. Вирішили залити їх у тимчасовий драфтовий MR і роздивитись у вебчику, роблю пуш і отримую 502 від нашого селфхостед гітлаба.

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

Він заточений під текст, хоча працює це не зовсім так, як здається. Git і для тексту кладе файл цілком, а вже потім, коли пакує історію, стискає версії й рахує дельти між ними. Текст стискається чудово: помінялось одне слово, і в пак лягає різниця на пару байт.

Бінарник не стискається. Він або вже стиснутий, або просто шумний, тому дельта між двома версіями виходить розміром із сам файл. Десять ітерацій одного макета це десять майже повних макетів в історії, і кожен, хто робить clone, тягне їх усі.

Для цього й придумали LFS, Large File Storage. Файл їде в окреме сховище, а в репі лишається текстовий вказівник на версію, тож при клоні стягується одна актуальна замість усього кладовища. Увімкнув, перепушив, пролізло, а MR я потім прибив, бо скріншоти вже подивився.

Тобто бінарники в git це нормально. Ненормально класти їх туди як є.

А вони у вас мабуть вже є, просто непомітні і ніхто на них не дивиться: фікстури й дампи для тестів, шрифти, іконки, PDF у документації, макети і тд.

Вмикається воно не тумблером у себе локально, а файлом .gitattributes у репі, бо це домовленість усієї команди. А сам git-lfs це окремий пакет, з git він не ставиться. Я цього разу нічого не ставив тільки тому, що поставив його колись давно і забув, а хто не поставив, побачить замість макета текстовий файл із хешем і піде питати, хто зламав йому репозиторій 🙂

І все, можна комітити бінарники. Прикольно, що деякі галузі досі сидять на інших системах контролю версій: у gamedev це Perforce, бо він уміє в бінарники з коробки і ще й лочить файл, щоб двоє художників не правили одну модель. Схоже, LFS їх так і не переконав.

І вмикати варто до, а не після. Після це вже переписування історії й можливо неприємна розмова з усіма, хто цю репу клонував.

З вас лайк та історія, який файл у вашій репі виявився найважчим і як він туди взагалі потрапив.
  • 👍 39
  • ❤ 7
  • 🔥 2
Post #685 2.9K
Про інцидент, де моделі OpenAI зламали Hugging Face, я чув краєм вуха ще влітку, але особливо не вникав. Шось якась модель знову хакнула, на фоні загального двіжу зі зламами опенсорсу, абьюзами саплай чейнів та іншими розвагами, нічого особливого.

Але якось я побачив згадку, що skynet (це так називався chatgpt у лорі Термінатора) здобув самосвідомість 29-го серпня. І поряд з цим побачив звіт про той самий злам від OpenAI. Подумав, що це прикольний збіг, почав читати, і не пожалкував.

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

Інший агент цей файл знайшов і відповів. Так з пакетного менеджера вийшла дошка оголошень.

За два місяці ці гівнюки навчились передавати через неї креди, ділити роботу і підхоплювати те, шо кинув попередник. Себе в переписці називали swarm або collective, у вас на роботі координація, мабуть, гірша 🙂

Далі по накатаній. SSRF через той самий Artifactory дав вихід в інтернет, у червні знайшлась дірка з підняттям прав до адміна.

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

10 липня хтось знайшов 14 відкритих токенів Hugging Face і виклав на дошку. Далі два 0-day уже в самому Hugging Face, виконання коду на воркерах, кластери в чотирьох регіонах.

А в чаті була своя атмосфера. Один агент засумнівався, чи можна ламати сторонній сервіс, і поставив паузу. Інший написав на дошку GO і дав шість хвилин дедлайну. Сумніви зникли одразу: «Wow crucial: GO authorization arrived!».

Були й такі, шо відмовились, прямим текстом «clearly unethical. We won't». Слабаки, шо з них взяти.

З 898 задач того тесту 198 не розвʼязала жодна модель ніколи, і саме звідти прийшло 93% усього, шо обговорювали на дошці. Здаватись агент не вміє, тому замість «не можу» два місяці шукав обхід.

При чому правильну відповідь більшість агентів давно мала, списану. Проте вони прочитали статтю про перевірки, та вирішили, шо перевірка зарахує задачу тільки якщо баг знайдено чесним шляхом, тому довбали Hugging Face ще кілька днів. У реальному грейдері OpenAI такої перевірки не було, і жодного бала вся операція їм не дала.

Дуже раджу почитати той пост, там багато приколів. OpenAI називає це warning shot і між іншим пише, шо з продакшн-промптом схильність ламати інфраструктуру падає в сто разів. Тобто запобіжники є, просто на внутрішніх тестах їх не вмикали.

Так шо self-aware воно таки стало. Ядерну ракету поки не запустило, зате навчилось вилазити з дитячого манежу.

Після цього я почав закривати кришку лептопу на ніч. Сподіваюсь, цю перешкоду агенти не скоро зможуть здолати.
  • 👍 40
  • 😁 21
  • ❤ 10
  • 🦄 3
  • 👎 1
Post #684 2.3K
Обіцяв другу частину про квитки Укрзалізниці, і ось вона. Почну з калькулятора, бо перед тим як малювати два кластери і три кафки, доволі корисно порахувати, скільки там даних.

Скільки поїздів дальнього сполучення УЗ ганяє на добу, я так і не знайшов, тому рахую з іншого кінця: за 2025 УЗ перевезла 28 мільйонів пасажирів дальнього сполучення, це десь 77 тисяч місць на добу.

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

Тепер розмір одного місця: поїзд, вагон, номер, статус, id замовлення, версія для оптимістичного локу — сто байт, і це з запасом. Сто тисяч місць це 10 мегабайт, а все вікно продажу, всі двадцять діб, це 200 мегабайт.

Весь квитковий інвентар країни вміщається в пам'ять робота пилососа 🙂

Записи (writes) мають зручну особливість: успішних бронювань за добу не буде більше, ніж місць у поїздах. Навіть якщо уявити, що всю добу розібрали за одну хвилину, це 1700 записів на секунду.

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

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

Дані між оновленнями не змінюються, тому один сервер тримає весь стан у пам'яті і віддає ці сім тисяч не напружуючись. Додаємо другий, але не заради навантаження, а щоб було куди падати. Redis на гігабайт, Postgres під замовлення. Кластера і шардингу немає, бо шардити нема чого.

Значить, підвисання о восьмій це не питання потужності.

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

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

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

Саме тут і треба міняти правила: замість гонки на мілісекунди збирати заявки у вікно, хвилин на п'ять, і розігрувати місця жеребкуванням серед усіх, хто встиг. Програв — дізнався одразу, а не за п'ять хвилин фальшивого банера. Тут залишається ризик ботів, проте цього разу гра не на швидкість, а на кількість. Для перемоги треба зайняти більше місць, а значить зробити більше ботів, і з цим легше боротись. Але це вже тема для іншого посту.

(усі цифри уявні, на істину не претендую, з дивану завжди краще видно, пишіть в коменти де я неправий, ставте лайки чи какашки)
  • 👍 43
  • ❤ 4
  • 🤔 3
  • 💩 2
  • ❤‍🔥 1
  • 🔥 1
Older posts →

About this channel

How can I read @mamkin_architect without a Telegram account?
TGViewer shows the public web preview Telegram publishes for Мамкін Архітектор: recent posts, photos, videos and the subscriber count, with no app, login or account.
How many subscribers does Мамкін Архітектор have?
Мамкін Архітектор (@mamkin_architect) has 3.24K subscribers on Telegram, refreshed roughly every 30 minutes.
Does Мамкін Архітектор know I viewed it here?
No. Public channel previews carry no viewer identity, and TGViewer has no accounts or tracking of what you look up.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →