Стендап Сьогодні

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

Підписатись на RSS
📢 Канал в Telegram @stendap_sogodni
🦣 @stendap_sogodni@shevtsov.me в Федиверсі

14.10.2022

Чому ми обираємо один великий сервіс замість купи мікросервисів

🐳🤝🐳 Сьогодні з двох сервісів вирішили зробити один. І то навіть не мікро-, а дуже такі макросервіси. Просто підстава причина мати два окремих сервіси. І то добре

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

Є декілька приводів робити більше одного сервісу:

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

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


13.10.2022

StarCraft - моя улюблена стратегія

🧑‍🚀👽🐜 Сьогодні несподівано пост про Старкрафт.

Цікаво що це як не найперша “справжня” гра в моєму житті. Хоча двадцять років тому Старкрафт мені не зайшов, бо я навіть не зрозумів, що там є карта, і чому вона вся чорна. Потім вже, набагато пізніше, розібрався, але крутим гравцем ніколи не став. Більше подобалось побавитись з чітами, або грати цікаві мапи супротив компʼютера.

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

На мою думку, кампанія взагалі не дуже “стратегічна” гра у тому сенсі, що вона ніколи не є чесною грою, а натомість є чередою головоломок. Кожна місія ставить особливе випробування, а задача гравця — зрозуміти, що воно є, та впоратись.

Моя улюблена місія — то сьома місія за протоссів Homeland. Задача її — розбити нексус (тобто, центральну будівлю) противника. Противник набагато сильніше за тебе: в них є найбільш просунуті юніти, недоступні гравцю, а також добре захищені бази. До того ж боти невпинно атакують. А ресурсів — тих, що не за вражими базами — обмаль. Таким чином, чесне “стратегічне” рішення місії дуже важке, мабуть, найскладніше за всю кампанію. Що ж робити?

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

Інколи головоломка очевидна — наприклад, місії, де гравцю забороняють повітряні юніти — а інколи треба дивитись на обставини — який надали юніт. Наприклад, попередня місія - Into the Darkness - потребує опанування і використання здатності героя копіювати юніти — галюцинація — бо карта повна ворожих камікадзе, що вибухають, і я просто не уявляю, як це пройти без виманювання їх на галюцинації.

Такий підхід дуже мені нагадує мій улюблений жанр ігор - Soulslike. А може, навпаки, за багато років соулслайків я вже звик не йти в лоб, а шукати головоломку.


12.10.2022

Додаток єППО - ідеальний перетин здібностей людини та машини

🚀👀📱 Зверну увагу на додаток єППО, що вийшов сьогодні. Він дозволяє будь-кому долучитись до захисту України від ракет — повідомляти про ракети та дрони, якщо побачиш їх в небі. Далі, як я розумію, дані агрегуються, фільтруються, та додаються до системи виявлення цілей.

(Дисклеймер: я ніяк з додатком та його авторами не повʼязаний.)

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

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

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

Повідомити, де саме вона летить, може як і додаток по API, так і людина за телефоном або месенджером. Але перше відбудеться за долі секунди, а друге — за хвилини.

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

У машини краще виходять облік, контроль, агрегація.

Щоб була синергія, треба і в маленькому, і в великому контексті шукати — де доля людини, а де доля машини.


11.10.2022

Бібліотека i18next як шар людської мови в додатку

📚🚲🌎 Для інтернаціоналізації в Javascript добре відома бібліотека i18next. Але вона буде корисна, навіть якщо ви поки не плануєте перекладати додаток.

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

Класичне інженерне рішення — просто змінити текст так, щоб плюралізація на нього не впливала. Наприклад, замість “5 повідомлень” - “повідомлень: 5”. Швидко, просто, зовсім не якісно.

Наступний рівень — винайти власний “ровер”, ну, наприклад, функцію, що приймає кількість та варіанти тексту. Або, для англійської, додає закінчення “s” та, якщо здогадається, обробляє винятки. Підходів багато, але спільне в них те, що якісний плюралізатор вийде доволі складним. (Тому я і раджу почати з функції, що приймає текст для однини та множини — це рішення просте та надійне, хоч і не “елегантне”.)

Так от, якісний та довершений плюралізатор вже є в i18next. Як і інші засоби роботи з текстами:

Взагалі, я дивлюсь на i18next як на “шар людської мови” - тобто єдине місце для всіх рядків, що призначені для читання користувачами. В іншому коді мають вживатись тільки ключі до словника i18next.

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


10.10.2022

Спеціалісти схильні ускладнювати ситуації в свій бік

👨‍🔬👨‍⚕️👨‍🏭 Кожний спеціаліст дивиться на ситуацію з боку своєї спеціалізації, і так само ставить задачі.

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

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

Тому цінний той стоматолог, який скаже, що поки що ніяких пломб ставити не потрібно. А програміст — той, що не буде робити сайт-візитку на Ruby on Rails.

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

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


09.10.2022

Бібліотека react-native-health та кодогенерація

⚛️🍎❤️ Продовжив розбиратись з react-native-health. Дуже швидко натрапив на проблему: в обгортці не вистачає функції preferredUnitsForQuantityTypes ; як, до речі, і в обгортках, що з нею конкурують. Тобто не можна отримати налаштування одиниць вимірювання, і доведеться питати користувача окремо.

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

Додати в обгортку для React Native один метод на Objective C справа цілком реальна і багато часу на це не пішло, хоча на Objective C я пишу “зі словником” (а насправді з гуглом, авжеж). Навіть якщо обгортку треба писати з нуля, то можна впоратись за пару годин. Objective C - одна з найменш зрозумілих для мене мов, синтаксис ні на що не схожий.

Але тут стала інша проблема. Категорії значень — вхідне значення методу — треба передати у вигляді типу HKObjectType. В JavaScript, відповідно, треба передати рядок, який потім перекласти у цей самий тип. Простого методу для цього немає, бо в Objective C так не роблять — автори бібліотеки цілком раціонально очікують, що ми будемо вживати готові константи, а не довільні рядки.

Тобто треба написати словник. Можна побудувати його вручну. Але ж є проблема — на цей час в HealthKit існує 182 різних типи значень, а в майбутньому зʼявляться ще. (Зауважу, що для розв’язання моєї задачі вистачило б одного типу. Але яка в тому втіха?)

На допомогу знову приходить кодогенерація. Я знайшов файл, де перелічені всі ці типи - HKTypeIdentifiers.h (Він вже схожий на згенерований, до речі.) Далі рядки файлу можна розібрати регулярним виразом, побудувати перелік типів, і згенерувати для них як словник для Objective C, так і декларації для JavaScript/TypeScript.

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


08.10.2022

React-Native та Healthkit

🍂🎨💓 Взагалі сьогодні гуляв з сином, а потім фарбував стіни, тож день видався цікавим.

Але як щодо айтішних подій, то випробував роботу React Native з Apple Healthkit. Для цього є бібліотека react-native-health. Працює.

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

І з іншого боку — буде можна спростити додаток, не робити власного сховища, синхронізації, авторизації та іншого.

В мене є пара ідей для інтеграції з Healthkit. Перша така — дозволити обрізати тренування, якщо ти забув вчасно його вимкнути. Чомусь немає такої вбудованої функції, і мене це дратує кожного разу.

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


07.10.2022

Скорочення повторюваного коду на Go за допомогою кодогенерації

🐹🧙📑 Сьогодні рефакторив модуль на Go, в якому розплодився допоміжний код. Код такий, що не піддається звичайному розділенню на функції, а його треба копіювати з маленькими змінами багато разів. Тобто те, що називається boilerplate.

В Ruby таке вирішується метапрограмуванням. В JavaScript на функції можна розбити практично все. В Clojure код — це дані, тож проблема не існує концептуально. А що в Go робити?

Go - мова дуже проста. І з копіпастою справляється простим засобом — генерацією кода. Для цього є директива go generate. Її доцільно вжити, якщо ви бачите, що копіпаста не піддається рефакторингу.

Приклад задач, які я вирішував генерацією:

Генерацію кода дуже просто написати, я зазвичай роблю шаблон — буквально модулем text/template. Нічого особливого в генераторах немає, це може будь-яка програма будь-якою мовою.

Нарешті, помічаємо файли як згенеровані, щоб GitHub їх приховував.


06.10.2022

Як провести стрес-тест, з якого можна робити висновки

📏⏱️⚖️ Що робити, щоб довести, що ваша архітектура витримає навантаження, що потрібне для комерційного успіху продукту? Це життєво важливе питання для майбутнього інвестора.

Можна зробити стрес-тест у повному обсязі. Інколи це можливо зробити, і не за скажені гроші: сучасні хмарні системи, такі як AWS, дозволять виділити ресурси тільки на годину або ще менше. Ще залишається задача підготування відповідної кількості даних.

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

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

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

Деякі бази, такі як AWS Redshift, мають вбудоване масштабування. Тоді можна зробити стрес-тест ваших запитів на одному вузлі, потім на двох, на чотирьох, і при вдалій схемі побачити лінійне (чи може, логарифмічне) прискорення.

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

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

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


05.10.2022

Як автоматизувати наповнення AWS Parameter Store

🤖✍️⚙️ Сьогодні довелося записувати в AWS Parameter Store цілу купу однотипних сертифікатів. По два сертифікати на чотири сервіси та ще й у трьох оточеннях… виходить 24 параметри. А ще на кожний параметр треба задати опис та шифрування. А ще вони в різних регіонах…

Руцями робити ніяк не хочеться, та й не довіряю я собі. До того ж вебінтерфейс AWS на редагування особливо жахливий і накладає додатковий ризик помилки. Які ще є варіанти? Насправді багато.

Можна зробити конфігурацію Terraform на один раз. Створити всі параметри, перевірити, що все працює, а потім просто викинути файл стану (та й саму конфігурацію). В Terraform весь звʼязок “з реальністю” міститься саме в файлі стану, тому ніяких “хвостів” потім не залишиться, тільки самі параметри. Тут зручно що можна використати цикли Terraform, щоб спростити собі роботу.

Можна написати скрипт, що за допомогою AWS API зробить все потрібне. На один раз це трохи складно. Але в нас навіть вже є такий скрипт, що завантажує параметри з YAML-файлу. Скрипт доволі багатофункціональний, і я його часто вживаю. Втім, він не вміє задавати описи параметрів.

І ще один, напівавтоматичний гібридний спосіб — взяти AWS CLI. Взагалі, якщо працюєш з AWS, то його завжди треба мати під рукою, бо багато чого вміє, від завантаження з/на S3, до усіляких деплоїв та взагалі будь-чого, що буває в Амазоні.

Так от, створив шелл-скрипта, у якому написав один рядок команди aws ssm put-parameter з усіма аргументами — імʼя, значення, опис, регіон. А потім його накопіпастив і відредагував те, що змінюється (таке легко робити мультикурсорами у VSCode.) І все, запустив скрипт — отримав результат. Ідеальний баланс автоматизації та ручної роботи для одноразової події.