Стендап Сьогодні
Що я зробив, що я хочу зробити, і що це все значить.
Повсякденні здобутки в форматі стендапу.
Детальніше в статті
Підписатись на RSS · 📢 Канал в Telegram @stendap_sogodni
04.07.2024
GitHub Codespaces: на диво гарно!
Сьогодні мав перший досвід роботи у GitHub Codespaces. Це, так би мовити, “хмарне робоче місце”: віртуальна машина з приєднаним редактором, на якій можна вести розробку. Перші враження такі, що це дуже гарне рішення, та якщо вам щось таке потрібне, можна не вагатися.
Перше, що помітиш, це безшовна інтеграція з VSCode. Одна з визначних, хоч і прихованих можливостей VSCode - це клієнт-серверна модель виконання. Тут вона працює на повну, та віддалений проєкт практично не відрізняється від локального. (Єдине, що термінал — не редактор — все ж гальмує, але і тут вони помʼякшили: все введене в термінал моментально зʼявляється “примарними” літерами, а після обробки на сервері вони стають звичайними.)
Зміст проєкту береться з репозиторію GitHub, що очевидно. Також під час створення кодспейсу він питає гілку — а це трохи спантеличило. Але мається на увазі гілка із конфігурацією кодспейсу, яка тут робиться у форматі devcontainer. Далі ми вільні переходити в будь-яку гілку та й взагалі робити, що хочемо. Також можна надати доступ до інших приватних репозиторіїв. Технічно можна навіть створити кодспейс з порожнього репозиторію, а потім підтягнути туди абсолютно інший код.
Всередині отримуємо більш-менш стандартну віртуальну машину з Debian. Головне, що Docker працює. Також маємо можливість доналаштувати, причому, що мені подобається: як спільне для всіх оточення, так і персональне (за допомогою dotfiles). Оце важливий момент: Codespaces це інструмент для команди, тобто досвідчений інженер може налаштувати середовище, яке потім легко запустить будь-хто з колег.
Це приводить нас до питання: кому таке потрібно? Та, як на мене, саме оказійним розробникам. Наприклад, може у вас є підпроєкт, який не всім та не завжди потрібний; можна налаштувати для нього кодспейс та будь-хто з команди зможе долучитися з дрібними змінами. Або інший випадок: для безпеки та ізоляції. Щоб код проєкту та його залежності не потрапляли на локальні диски розробників, вони можуть працювати з ним в кодспейсі. В мене як раз така потреба й виникла, та дуже радий, що я можу майже непомітно перестрибнути у хмарне середовище.
Що тут можна сказати. Microsoft не дарма володіє GitHub, VSCode, та Azure!
03.07.2024
Як запобігти вигорянню на роботі
Поступило питання, яким чином я ще не вигорів на роботі. Ну, давайте так: хто сказав, що не вигорів? Пройшов декілька тестів та отримав результати: від малих до помірних ознак вигоряння. Але за самооцінкою я б сказав, що просто життя зараз складне, тому було б дивно, якщо таких ознак не було.
Що мені допомагає?
-
Сон, добра їжа та тренування. Це фундамент всього самопочуття. Що б не було, я стараюся висинатися, їсти здорово та робити хоч щось спортивне. Хоча б довгу прогулянку під подкаст. Якщо в тебе є симптоми вигоряння, раджу почати саме з цієї трійки.
-
Робота, де я маю високий рівень контролю. Як над собою: гнучкий графік, відсутність мікроменеджменту. Так і над продуктом: у нас в культурі висловлювати думку, а не просто “робити, що сказали”. Почуття контролю, гадаю, дуже важливе для запобігання вигорянню. Як то кажуть, за кермом не нудить.
-
Схильність до прокрастинації. Дійсно! Я більше відчуваю хронічне недонавантаження, ніж перенавантаження. Гадаю, це не корелює з реальністю, просто мій психотип схильний так бачити світ. Вигоряння для більш дисциплінованих — моя конячка зайвий вантаж скидає.
-
Ну то й безумовно, підтримка близьких та можливість відверто поділитися турботами та самопочуттям. ❤️
02.07.2024
Правило лісника
Сподіваюся, всім відомо правило скаута: залиш місце чистішим, ніж яким його знайшов. Воно доречне як в лісі, так і в коді. Проте для лісника такого правила недостатньо. Лісник також повинен стежити за загальним порядком та створювати сприятливі умови для відвідувачів.
…Щоб не затягувати з метафорою: в команді лісник — це лід інженер. Та лід інженеру мало зробити задачу та переконатися, що всі лінтери проходять. Окрім того, якщо у виконанні зустрілися очевидні перепони, то їх потрібно усунути — або принаймні внести усунення в план.
Наприклад, якщо виправлення помилки показало, що в цьому місці бракує тестів, то потрібно — не писати всі тести за раз — а принаймні підготувати під них базу. Або трапляться що код потребує системного рефакторингу, а кожна окрема задача ніби недостатньо зачіпляє, щоб його робити. Або документацію потрібно написати. Або оновити фреймворк.
Всі ці задачі критично важливі для продукту, та очікувати що обʼємні зміни будуть зроблені “мимохідь” хибно. Або більше, вимагати цього від всіх інженерів. Якщо кожен інженер буде зупиняти заплановану роботу, щоб провести масивний рефакторинг, то темп розробки стане вкрай непередбачуваним.
На то і є головний інженер, щоб уважно стежити за появленням технічного боргу, та робити життя краще для всієї команди.
01.07.2024
Правильний формат адреси бази даних
Здавалось би, це тривіальне питання, але я тільки виринув з масивної зачистки Terraform та вже так не думаю. Найперший вибір — це URL. Причому, URL це не аби що, а рядок, що починається зі схеми… та продовжується на кшталт:
postgresql://myhost.db:1234/mydb?pool=10
URL гарний тим, що в будь-якому середовищі є стандартний спосіб його розібрати. Також це самодостатній формат — в ньому є місце не тільки для адреси, а й для авторизації, додаткових параметрів тощо. Наприклад: потрібно вимкнути TLS для локальної розробки? Це зазвичай можливо без залучення додаткового параметра чи логіки.
Інший раз бачу, параметр називається URL
, а всередині пара host:port
. Це небезпечно, бо така форма не є URL та призведе до помилки, якщо спробувати її розібрати. Інколи таку пару називають addr
, бо вона позначає адресу TCP/IP… або позначала б, якщо замість імені хосту була IP-адреса. Ще є чудовий параметр-сюрприз endpoint
. Ця назва взагалі нічого не каже про свій зміст.
На тлі всього цього URL гарний просто тим, що з ним все ясно. А будь-який інший формат, який може захотіти клієнтська бібліотека, можна з нього отримати.
Ще альтернатива: кожний елемент вказувати окремим параметром: host
, port
, username
, password
. Це може бути зручно, якщо хост приходить з Terraform, а пароль — зі сховища секретів. Але з інших боків зайві параметри тільки ускладнюють налаштування.
30.06.2024
Власні значки в стилях для Obsidian
В реалізації стилів для канви залишався недолік: для значків я був обмежений символами звичайного шрифту — що незручно ще до того, як згадати, що шрифт може змінюватись. Зміст значка в мене утворюється директивою CSS content
. Пробував замінити його на SVG - не зміг редагувати колір того SVG (в межах CSS).
Сьогодні розвʼязав цю задачу остаточно. По-перше, знайомтеся, Nerd Fonts. Це шрифт, в якому зібрано 10 тисяч (!) значків з різних відкритих наборів. Шрифт мене влаштовує краще, ніж SVG, бо з ним можна працювати як зі звичайним текстом. Але тепер, як додати його прямо у CSS?
Виявляється, CSS вміє завантажувати шрифти з data URL
. Може, то й очевидно, але я з data URL стикався тільки для зображень. А тут можна отак:
@font-face {
font-family: "Nerd Fonts Symbols Embedded";
src: url(data:application/font-woff2;base64,d09... ще мільйон символів);
}
Тільки один нюанс: шрифт розповсюджується в форматі .TTF
- це зручно для використання в редакторі, але для Obsidian потрібний шрифт .WOFF2
, бо він побудований на вебтехнологіях. Дізнався, що насправді WOFF2 це лише добре запакований TTF, та для перетворення є проста утиліта.
Нарешті, останній момент: щоб використати той значок в CSS, треба писати щось на кшталт content: "\f128"
; код символу береться з каталогу. (Або тягнути вбудований CSS Nerd Fonts, але мені то заради пʼяти значків занадто. До речі… сам шрифт пізніше теж можна було б підрізати точно під потребу.)
29.06.2024
Стохастичний таймтрекер та робота
Хоч розробка таймтрекера трохи уповільнилася — але користуюся я ним постійно та веду охайний облік власного часу. От, роздивився, чи може такий облік допомогти для робочих звітів.
(Нагадаю, що СтохастичнийТаймтрекер — на відміну від класичного — питає тебе у випадкові моменти, чим ти займаєшся на той самий час. З одного боку, це не так точно, з іншого боку — не потребує відстежувати кожну активність вручну, та тому краще виявляє відволікання та зміни контексту.)
Почну з очевидного: точних до хвилини звітів тут не вийде. Я б навіть сказав, що в межах одного дня теж нічого конкретного не отримаєш, бо за робочий день можна отримати як два пінги, так і двадцять.
Але чи дійсно такі звіти потрібні, якщо все одно вони агрегуються в статистику на місяць? На такому масштабі стохастичний трекер вже цілком точно вимірює витрачений час.
В минулому я тегував час за субпродуктом та категорією активності (програмування, пошук помилки, комунікація, …) Категорія активності це корисно, субпродукт — не настільки; було б краще тегувати за епіком (навіть напряму — кодом задачі.) В наступному місяці спробую, бо повинно вийти дуже наочно. Також спробую розділяти активності за обовʼязками (наприклад, комунікація — це може бути допомога, чи навпаки пошук допомоги, чи дискусія тощо)
Цікаво побачити, скільки часу уходить на побічні активності; обовʼязки як перегляд PRів здаються такими що відбирають багато часу, але на практиці витрати мінімальні. Хоча це нічого не каже про ментальне навантаження — можливо, в майбутньому почну відстежувати і його рівень.
28.06.2024
Зачистка AWS Parameter Store (та магія jq)
Чудова пʼятнична забава: знайти неавтоматизовані параметри в AWS Parameter Store. В ідеалі, все повинно потрапляти туди через Terraform або іншу автоматику, але ж неодмінно деякі дані протікають вручну.
Очевидно, що вручну я того робити не буду: параметрів за тисячу, це просто нереально. Та також не потрібно. Список параметрів можна отримати через CLI:
aws ssm get-parameters-by-path --path '/' --recursive | jq -r '.Parameters[].Name | sort'
Тут окрім самого AWS CLI використовується утиліта jq. Вона виконує складні перетворення JSON в один рядок; тут ми беремо атрибут Parameters
, який є масивом, а з його елементів беремо атрибут Name
.
…Тепер за Terraform. Спочатку я хотів шукати кожне імʼя параметра вручну… проте це ще гірше, бо імʼя може конструюватися з відрізків, повторюватись і таке інше. Зате всі параметри сидять в стані. Тобто достатньо стягнути стан та (оскільки це теж JSON) забрати те, що потрібно:
terraform state pull | jq -r '.resources[] | select(.type=="aws_ssm_parameter") | .instances[].attributes.name | sort'
Тут алгоритм складніший, але JQ впорається з тим, щоб знайти ресурс правильного типу.
Залишається тільки порівняти дані командою diff
та результат готовий! На жаль, не так легко з’ясувати, які з параметрів дійсно потрібні, а які зайві… зате потім можна згенерувати за шаблоном файл Terraform чи навіть вхідний файл 1Password для секретів.
27.06.2024
Split_tests - швидші збірки на CI
Є в мене стара, але досі корисна утиліта: split_tests. Вона, попросту, розбиває довжелезний запуск тестів на декілька паралельних потоків, за набором файлів. Так збірку довжиною в годину можна виконати навіть за 10 хвилин. (На жаль, підготовка до тестів теж займає час, тому є розумна межа на кількість потоків.)
Для того потрібний тестовий пакет, який на файли можна розбити: наприклад, RSpec, або Mocha (А ось з Go вона ще не працює, хоч на Go написана — бо Go ділить тести на модулі, а не файли.)
(🦀 Як каже аксіома, до моєї реалізації на Go є реалізація з альтернативного всесвіту на Rust: split-test. Ні, серйозно!)
Колись давно я написав цю утиліту для CircleCI. А потім невдовзі там зʼявилася вбудована команда, яка робить те саме. Потім я опинився на GitHub Actions, та утиліта знову стала до нагоди — альтернатив тут немає, а ті що є, написані або на основі моєї утиліти, або схожих.
Як воно працює. Зрозуміло що ми хочемо досягнути рівного часу виконання на кожний потік. Прийнятного результату дає розділення файлів за кількістю рядків. Звісно, трапляються аномалії, де тривалість не корелює з довжиною. Тому також можна розділяти за історичними даними за тривалістю кожного тесту. Але тоді потрібно ті дані зберігати.
Або, можна знайти аномалії вручну та викликати їх окремо. Оце на мою думку оптимальний варіант. І технічно просто, і результат надійний. Зазвичай ті “аномалії” виявляються величезними інтеграційними тестами та їх в застосунку лише декілька.
26.06.2024
Статусні коди SMTP в порівнянні з HTTP
У SMTP, як і HTTP, сервер відповідає статусним рядком, який складається з коду та розшифровки. (Хоч на відміну від HTTP, SMTP - це діалоговий протокол, але діалог закінчується статусом.) Ніби все дуже красиво, багато цифр та взагалі все зрозуміло:
421 4.7.0 [TSS04] Messages from a.b.c.d temporarily deferred due to user complaints
Проте є ціла низка проблем. По-перше, відповідь SMTP має більше варіантів, та нам важливо розрізняти їх. Наприклад, статус вище значить, що ми повинні відкласти надсилання на деякий час, а потім спробувати ще. Якщо ми цього не зробимо, то ризикуємо потрапити вже в постійний блок. З HTTP рідко трапляються такі нюанси, а з SMTP це нормальна ситуація. Також потрібно розуміти, чи стосується помилка конкретного листа, чи отримувача, чи відправника, чи технічних причин — на кожний випадок є своя реакція.
По-друге, між серверами SMTP немає однорідності. Наприклад, статус 421
означає “сервер тимчасово недоступний”. Але у випадку Yahoo (який і видає наведену відповідь) значення інше: нам варто призупинити все надсилання пошти на декілька хвилин, щоб підтвердити власну відповідальність. Якщо ігнорувати такі рекомендації, потраплятимеш в блок.
Навіть на сторінці Вікіпедії про ці статуси наведені їхні приклади, а не перелік. Максимум, на що можна розраховувати — це те, що статус 4xx
тимчасовий (тобто варто спробувати пізніше), а 5xx
постійний. Але це не допоможе зрозуміти, чи нам потрібно відписати адресата, чи виправляти зміст листа, чи щось інше.
Щоб боротися з цим, ввели додатково розширений статус — це в прикладі 4.7.0
. На жаль, з ними так само немає однорідності, тому я якщо чесно погано розумію, чим вони допомагають. Все одно, щоб зрозуміти тип відповіді, краще дивитися на весь її зміст.
Але є й позитивна сторона: популярних серверів SMTP не так багато, тому цілком реально покрити їхні відповіді зі впевненістю. Навіть GMail один покриє десь третину всієї пошти. Виходить парадоксальна ситуація: хоч можливих статусів необмежено багато, але уваги потребує небагато (так, як статус TSS04
від Yahoo.)
25.06.2024
10 годин зачистки Jira
Весь день провів за зачисткою Jira. Це частина того, що потрібно було зробити для “чистоти думок” за GTD. (На роботі ще залишилися декілька PRів, які давно висять, та декілька десятків незавершених гілок — це в мене часта ситуація.)
Для мене Jira, як я зараз бачу — це місце для контрактів. Кожна задача — домовленість (контракт) між людьми про роботу, яку треба спланувати, виконати, перевірити та вивести у світ. Як я тільки нещодавно писав, це погане місце для ідей, поки вони не набули конкретики.
Про місце для ідей команди я ще буду думати, але поки на особистому рівні я перебирав всі задачі, до яких маю відношення, та переносив у власну канву “мабуть/колись” з належним групуванням. Також багато задач було скасовано. А декілька навіть вдалося виконати “на ходу”, бо звісно ж задачі на 10 хвилин можуть роками сидіти в беклозі без уваги.
Гадаю, для багатьох інженерів задачі в Jira заводить менеджер, а бере вона їх… з іншого місця, де відбувалося планування. Знов-таки, бо в Jira потрапляють готові контракти. Але в мене трошки інша ситуація, бо велика частини роботи “знімається з оточення”, та її треба десь занотувати та підготувати до виконання. Тому мені й потрібна додаткова зовнішня система.
До речі, мені зрозуміло, що таку зачистку потрібно робити частіше, напевно, раз на ітерацію. Коли один раз все зачистив, далі можна додати до пошукового запиту обмеження на updated
та передивлятися тільки нове. (До речі, Jira - це база даних, та знання пошукових запитів допомагає змусити її працювати на тебе.) Потім можна експортувати результати запиту в CSV та робити з ним вже все що завгодно. Я, наприклад, генерую список, розбитий по статусах.