Стендап Сьогодні
Що я зробив, що я хочу зробити, і що це все значить.
Повсякденні здобутки в форматі стендапу.
Детальніше в статті
Підписатись на RSS
📢
Канал в Telegram @stendap_sogodni
🦣
@stendap_sogodni@shevtsov.me в Федиверсі
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. Її доцільно вжити, якщо ви бачите, що копіпаста не піддається рефакторингу.
Приклад задач, які я вирішував генерацією:
- заміну складних обгорток CGO
- генерацію сервера HTTP API з оголошень RPC
- оптимізовані кодеки для формату MessagePack без рефлексії, бібліотекою go-codec
- парсер для внутрішньої мови за допомогою бібліотеки pigeon.
Генерацію кода дуже просто написати, я зазвичай роблю шаблон — буквально модулем 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.) І все, запустив скрипт — отримав результат. Ідеальний баланс автоматизації та ручної роботи для одноразової події.
04.10.2022
Нюанси міграції на TypeScript
☕🪟✨ Сьогодні довелося відповісти на пару питань про міграцію на TypeScript.
До своєї статті про перехід на TypeScript можу додати ще пару пунктів.
-
TypeScript - це все ж таки не “JavaScript з типами”, а мова, що семантично відрізняється. На TypeScript є власні ідіоми, які в JavaScript не поширені. Тобто при переході доведеться навчитися писати код по-іншому. Бо, з протилежного боку, деякий ідіоматичний код JS погано типізується і буде псувати все враження від TypeScript. А ще це значить, що деякий код набагато простіше переписати, ніж покрити типами.
-
Наприклад: випадки з невизначеним життєвим циклом змінних (або властивостей обʼєкта.) В JS ми просто приймаємо на віру, що присвоєння значення відбувається до його використання. TS з таким не погодиться, і вимагатиме, щоб при кожному звертанні до змінної ми перевіряли, чи вона має значення. Тут доцільно вжити discriminated union чи ізолювати змінні по меншім функціям.
-
JS побудований навколо парадигми “аби працювало, щоб ти не написав”. Звідси походять всі WAT та інше. В TS навпаки, тип завжди відомий, тому не потрібно стільки вгадувати значення та захищатись від несподіванок. Як плата за це, потрібно робити перевірки на коректність коду, які в JS здаються непотрібними - наприклад, про наявність індексу в масиві чи обʼєкті. Треба розуміти, що це і є цінність і мета використання TypeScript, і перевірки дозволяють уникнути помилок в крайових випадках, коли вони трапляться.
-
З чого почати типізацію? Моя порада — почніть з найпростіших типів. Зазвичай це значить почати з моделі та з маленьких функцій. Ще можна досить легко перекласти prop types для React до типів. До речі, потім prop types можна викинути.
-
Якщо десь не вдається розкласти по типах — то може бути й таке, що пора переписувати. А для цього краще мати добрі тести.
-
Не соромтеся оголошувати прості маленькі типи замість копіпасти, якщо декілька функцій чи компонент працюють з однаковими конструкціями.
03.10.2022
Клієнти для баз PostgreSQL - pgcli та SQLTools для VSCode
🗄️☁️🧰 Поділюся парою інструментів для доступу до баз даних SQL. (В мене це завжди Postgres, але інструменти універсальні.)
(Цікаво, що раніше якось завжди був поруч якийсь графічний клієнт — наприклад, phpMyAdmin, — а зараз немає ані в мене, ані у колег не бачу. Можливо, це результат того, що в Ruby on Rails зручніше писати запити в консолі на мові Ruby, це одна з величезних переваг RoR. Втім, інколи доводиться писати й чистий SQL. Для цього маю улюблені програми.)
pgcli - це просунутий клієнт PostgreSQL для командного рядка. Наприклад, там є підсвітка синтаксису, автодоповнення, і зручний показ результатів. А ще її можна запустити з URL бази даних замість купи параметрів. Працює також і з Redshift. Є варіанти й для інших баз даних. Я їм вже багато років користуюсь, тому вже забув, що там psql вміє робити.
Нещодавно ще почав вживати доповнення SQLTools для Visual Studio Code. Хотів, щоб був короткий цикл розробки: відредагував запит — запустив — подивився результати. І дійсно, це у SQLTools виходить чудово: редактор і результат запита ділять вікно навпіл. При цьому можна запускати як весь зміст файлу .SQL, так і один поточний запит, що взагалі дуже зручно. А ще SQLTools автоматично форматує скрипти, робить автодоповнення. Результати можна експортувати у CSV або JSON. Все це не виходячи з IDE та без копіювання запитів в інший додаток.
Так що зараз в мене вибір такий: для разових задач - pgcli, для розробки - SQLTools.
02.10.2022
Чуйка на проблеми - найважливіша якість інженера
⚙️💭💡 Сьогодні хочу розказати про найважливішу, на мою думку, якість інженера. Назву її “чуйка на проблеми”.
Що я маю на увазі. В нормальному стані людина приймає найочевидніші рішення, рухаючись несвідомо від ситуації до ситуації. Бо думати — це тяжко (без жартів.) І так відбувається не тільки з механічними діями. Можна несвідомо розвʼязувати досить складні інтелектуальні задачі, якщо ланцюг “очевидних” рішень виведе до розвʼязку (наприклад, відеоігри на цьому побудовані — бо там завжди є розвʼязок і шлях до нього.)
Нічого особливо поганого в такому підході немає, навпаки, він є природнім. Але ж всі ми знаємо ситуації, коли очевидний шлях був або неможливим, або безглуздим. (мій перший пост в Стендапі саме про це.) Тоді треба зупинитись, подумати, і знайти шлях краще.
Так от, ця моя “чуйка на проблеми” це здатність помітити, зупиниться і подумати. Оце головна риса інженера. Чуйку треба розвивати, щоб вона була як рефлекс. Бо вона нас має витягати с несвідомого автоматизму.
В мене, наприклад, є схильність ходити по колу при налагодженні. Хочу зекономити час, роблю прості зміни, потім беру першу гіпотезу і зациклююсь на ній. (Зауважу, що так трапляється в складних випадках саме тому, що в простих цей підхід чудово працює.) Потім в якийсь момент доходить — стоп! - що я роблю? а я це перевірив? а це? і розвʼязок знаходиться.
До речі, в багатьох робочих та побутових ситуаціях достатньо загуглити рішення, і воно знайдеться. Та й це забуваєш зробити, поки старанно намагаєшся впоратись.
…Ось ще сьогоденний приклад. Хотів купити дещо в Nintendo eShop. В Україні він взагалі не працює, тому в мене встановлений регіон США. А в ньому несподівано перестали працювати українські картки. Поспішав, перепробував вже купу карток і способів (PayPal, напряму, через поповнення кишені) - не хоче. А гугл моментально підказав, що треба було переїхати в Польщу, і картка Монобанку спрацювала без проблем. Треба було просто зупинитись і загуглити.
01.10.2022
Fly.io - зручна платформа для невеликих проєктів на Docker
☁️🏗️🎈 Хотів написати довший пост сьогодні про те, як заощадити гроші на хостингу, але виявилось, що економія доступна тільки в планах з місячною підпискою, тож пост буде коротше.
Мова йде про Fly.io. Це мій улюблений хостинг для проєктів-хоббі. Можна сказати, новітня заміна Heroku (а оскільки Heroku закрив безплатні плани — то саме час знайти їм заміну.) Але в Fly.io розміщають контейнери Docker. В наш час це найкращий спосіб розмістити свій додаток в інтернеті: він балансує добрий контроль над змістом і середовищем додатка, та простий і стандартний зовнішній інтерфейс. Будь то Rails, Golang або чийсь сторонній додаток — загорнути їх в Docker не ставить проблем.
Але вибір хостингу для Docker не такий великий. Є Heroku. Є, звісно, всі хмарні платформи — я дуже люблю AWS Fargate, але для малих проєктів це надто дорого і складно. Ще можна завжди підняти свій хостинг на будь-якому VPS, але тоді втрачається вся простота рішення.
На Fly.io місячна ціна починається з $1.94 (і до того поки що ще є безплатний ресурс.) При тому є всі сучасні зручності — метрики, CLI, власні домени з TLS, купа регіонів та інше. В мене вже пару років тут працює декілька додатків - RSS-читач та RSS-адаптер, система коментування для блогу, база CouchDB. Проблем не маю.
Як щодо згаданої вище економії: нещодавно Fly.io запровадили можливість вимикати додатки, коли в них немає клієнтів. Для малих проєктів це було б ідеально. Але, здається, такий функціонал доступний в платних планах від $29 на місяць.
30.09.2022
Дві різні адреси електронного листа
✉️✍️📭 Наступна дивина SMTP. Всі знають, що у листа є адреси “кому” та “від кого”. Але насправді у кожного листа є 2 пари адрес. Якщо проводити аналогію з паперовим листом, то одна пара — на конверті, а інша — на самому листі.
Технічно це виглядає так: електронний лист являє собою повідомлення формату RFC 5322, який дуже схожий на формат HTTP. Між іншим, в листі є заголовки, серед яких і From, і To. Тут все достатньо зрозуміло.
Але називати цей формат “форматом SMTP” буде невірно. Бо, як я вже казав, SMTP - діалоговий протокол, і весь лист, з усіма заголовками відправляється командою DATA. Так от що виявляється — перед цією командою сервер SMTP очікує команди MAIL FROM та RCPT TO, в яких також вказується відправник і отримувач! Це і є той самий “конверт” SMTP, визначений у RFC 5321.
Система електронної пошти, мабуть, за дизайном повторює пошту паперову, тому що значення на конверті використовуються для доставлення пошти адресату, а значення в листі — це те, що ми бачимо в поштовому клієнті. При чому адреси у листі та на конверті ніяк між собою не повʼязані та можуть бути абсолютно різними.
Який в цьому сенс? Я напевно не знаю, але знаю одну функцію пошти, яка на цьому базується, а саме BCC - “прихована копія”. (Я це несподівано дізнався, коли довелося її реалізовувати.) Коли ти вказуєш заголовок Bcc, то твій поштовий клієнт відправить лист без цього заголовку, але додасть отримувача в перелік RCPT TO. Так всі адресати побачать той самий лист, але не побачать, хто отримав приховану копію.
А ще спамери, звісно, зловживають цим, щоб дурити нас і підписувати листи ким хочуть. Лист, в якому заголовок From: та адреса MAIL FROM не збігаються хоча б за доменом, втрачає в автентичності, але все одно є шанс його отримати.
29.09.2022
Який сенс у тайм-трекінгу?
⏰📝💸 Багато хто не любить тайм-трекінг і бачить в ньому тільки інструмент бюрократії та терору. Я теж не люблю їм займатись, але це як чистка зубів — на тайм-трекінг є користь.
-
Якщо ти працюєш за гроші, то звіт про час потрібен як артефакт, який приблизно дублює виконану тобою роботу. (Принаймні без роботи звіт складно написати.) Тому замовник може по наявності звіту бачити, що робота робилась. Тут справа не в довірі, а в простих ділових відносинах. Бо всі ж розуміють що результат роботи він може і не побачити, тим паче оцінити. При цьому не стільки важлива точність записів (у сенсі часу), скільки їх кількість та детальність (у сенсі виконаних дій).
-
Звіт дозволить побачити розподіл уваги по проєктах, якщо їх декілька. Або скільки часу уходить на підтримку та багфікси — дуже важливий показник. А ще прикольно рахувати проєкти-хоббі або просто ті, на які нечасто витрачаєш час. Так, на розбудову Сінтри з мого боку витрачено близько 600 годин.
-
Звіт вимагає бути усвідомленим і думати про те, чим ти власне займаєшся. Цього нам всім не вистачає. Раджу робити звіт для себе, а не для когось. Чом би йому не бути також інженерним журналом?
З тим, щоб слідкувати вручну за кожною робочою подією, я фактично не впораюсь. Тому я знайшов для себе такий напівавтоматичний варіант: весь мій час занотовується програмою Timing. Вона будує досить добрий журнал дій. За цим журналом потім будую акуратний звіт. В ідеалі робив би це щотижня, але виходить щомісяця.
На останнє: якщо роботодавець прискіпливо дивиться на твій тайм-трекінг, то турбується напевно не про звіт, а про твою продуктивність в цілому. Тож треба не ображатись, а увімкнути усвідомленість та зрозуміти, що до цього призвело. (Або бігти — на то ваша воля.)

