Стендап Сьогодні
Що я зробив, що я хочу зробити, і що це все значить.
Повсякденні здобутки в форматі стендапу.
Детальніше в статті
Підписатись на RSS · 📢 Канал в Telegram @stendap_sogodni
29.07.2024
Покращення до css_parser - тепер в PR
Нарешті знайшов час зробити два PR до бібліотеки css_parser
для Ruby, про які я писав рік тому, а зробив ще у 2021-му. Кілька спостережень.
-
За три роки покращення залишились актуальними (тобто ніхто не зробив те ж саме або щось краще.) Я зробив новий бенчмарк, та разом вони дають десь 27% прискорення загальної роботи — в попередньому пості йшлося про прискорення в 3 рази, але то конкретно для функції, яку я замінив.
-
Опублікувати власні зміни не так легко, як здається! Як мінімум доведеться “вписати” їх у внутрішню логіку бібліотеки. Я прибрав дві інші оптимізації, які не були надто ефективними, але потребували ширших змін (бо ті зміни, що я відправив, обмежені двома функціями — та й те, я розбив по одній на PR.)
-
До речі, чому взагалі зробив PR зараз? Бо власну гілку треба було ще підтримувати, та в один момент вона припинила підтримувати сучасний Ruby. Взагалі у гілок завжди ця проблема: якщо не підтримувати, то вони ані оновлень безпеки не отримують, ані тим паче нових функцій. Тому я раджу завжди робити PR відразу. Проте це легко зробити з виправленням помилок (бо їм всі раді) та складніше з новим функціоналом або оптимізаціями.
28.07.2024
Тулінг
Розробка внутрішніх інструментів для команди — це одна з найцінніших, мультиплікативних активностей, яка здатна піднести ефективність на нові рівні.
В моїй практиці багато випадків, де задача просто не може бути виконана готовими засобами в розумні терміни. Мені згадується стаття You can’t buy integration; теза якої: так, існує безліч готових рішень для будь-яких задач та проєктів. Але “останній крок” до розвʼязку все одно доведеться робити нам.
Я чимало зустрічав згадок про визначні інструменти всередині Google або Facebook. (Ось, наприклад, цілий “перекладач” з внутрішнього тулінгу Google на відкриті альтернативи.) На жаль, так відбувається не просто тому, що великі компанії такі розумні, а через те, що в них є резерв часу розробників, який може вкладатися в інструменти (а також експерименти та все інше.)
Але й в менших компаніях варто помічати потребу та доробляти тулінг там, де він потрібний. Зазвичай це відбуватиметься для закриття поточної задачі. Наприклад, побачив, що пошук журналів займає непомірно довго — автоматизував.
Інші приклади: внутрішні лінтери для підтримки домовленостей. Дешборди для оцінки ситуації. Кодогенератори для прискорення типових задач.
27.07.2024
Конфігурація Obsidian у dotfiles
Продовжую уніфікувати оточення за допомогою dotfiles та Chezmoi. На черзі Obsidian: хоча б заради того, щоб стилі для канви були однакові. Дізнався дещо нове про Obsidian.
Щоб просто залучити файли, проблем немає: chezmoi add ~/vault/.obsidian
та й годі. Конфігурація Obsidian міститься в файлах, в решті решт. Деякі файли є специфічними для оточення, їх прибираю: bookmarks.json
, workspace.json
, starred.json
.
Всі встановлені плагіни знаходяться там же ж. Не дуже хотілося зберігати зміст плагінів у dotfiles
, проте іншого виходу, здається, немає: Obsidian не вміє встановити плагіни за переліком. Технічно, можна власноруч завантажувати плагіни безпосередньо з їхніх репозиторіїв, але це ускладнює підтримку.
До речі, про підтримку: в Chezmoi є корисна команда chezmoi diff
, яка вказує всі розбіжності dotfiles
зі справжніми файлами. А також chezmoi unmanaged
- перелічить ті файли, які ще не контролюються chezmoi. Тобто в цілому немає проблем, щоб змінити налаштування в самому Obsidian, а потім зберегти в dotfiles
. А ще є chezmoi merge
для того, щоб інтегрувати зміни — вона працює для шаблонів. (Файли без шаблонів можна просто скопіювати.)
Нарешті, трохи переймаюся про ситуацію, коли потрібно замінити тільки частину JSON - наприклад, якби закладки (локальні) та налаштування були в одному файлі. Хоча такого ще не зустрічав, та й рішення для цього є: скрипти для модифікації файлів. Тобто можна приєднати якийсь jq
та все буде добре.
26.07.2024
Списки задач, GTD та вичерпність
Пʼятничний пост про керування часом. GTD багато загострює на потребі мати вичерпний список задач, щоб звільнити голову. Однак я до нещодавніх пір розумів цю вичерпність неправильно.
Взагалі, “вичерпно” залежить від контексту. Можна вичерпно розкласти кожну дію на найпростіші кроки. Можна вичерпно перелічити всі справи — від сьогодні до кінця часу. Вичерпати всі сфери життя, всі ідеї до найбільш примарних…
Проблема в тому, що будь-яка вичерпність приносить на поверхню набагато більше, ніж в мене є можливість опанувати. Та от тільки зараз зрозумів, що все простіше та людяніше:
Система задач повинна вичерпувати голову. Не більше, не менше. Її задача в тому, щоб мені не доводилось нічого тримати в голові; щоб голова була вільна бути в поточному моменті. Отже, якщо ловлю себе на якомусь нагадуванні — оце як раз його треба записати.
Це настільки просто: GTD існує не заради каталогізації задач або ретельного відстеження кожного кроку… а тільки щоб спокійно робити свої справи. Може, для когось це очевидно, але я провалив чимало спроб через намагання зробити систему “вичерпною”. Також важливо було почати відокремлювати поточні справи від ідей та планів на майбутнє.
25.07.2024
Культура ввічливого обходу
🚸 Обходи (або ж “хаки”, а взагалі ми їх частіше називаємо англійською - “workaround”) - це шматки коду, які написані не так, як ми хочемо, а так, як довелося через проблеми в чужому коді котрий ми не контролюємо. Часто тимчасово — до виходу виправлення. Щоб код не наповнювався загадковими нелогічними рядками, обходи потребують чіткої демаркації.
👉 Як мінімум потрібний коментар: # це обхід, через таку причину
. Коментар допоможе побачити (та пробачити), що наступний код написаний не за правилами. (Бо знаєте, трапляється й таке, що бачиш дивний код, починаєш рефакторити… та через пів години розумієш, що так робити не треба було, бо код був хаком.)
🍝 До речі, рефакторити обхід — зазвичай погана ідея… принаймні коли відомо, що потім його доведеться прибирати. Це той випадок, коли краще зробити прості (структурно) зміни та залишити їх. А якщо обхід стосується декількох місць — то варто перелічити їх в коментарі: # не забути подивитись на foo.rb та bar.go, коли будеш прибирати
.
📦 Окремо цікаво, коли обходи стосуються залежностей. Я не люблю package.json
та go.mod
за те, що в них не можна додати коментарі. Натомість в Gemfile
в Ruby можна додати скільки завгодно. Тут коментар виглядає як # під час оновлення перевірити цей файл та таку поведінку
.
🎫 А в ідеалі в коментарі до кожного обходу повинен бути тікет. Або такий, що вже існував та ми його тільки знайшли на GitHub - або можна (та варто!) створити власний.
Ось мені довелося освіжити файли конфігурації оболонки та дуже не вистачало пояснень до того, чому я написав декілька дивних рядків.
24.07.2024
Підготовка dotfiles з Chezmoi
Я досяг початкового успіху — зробив єдині dotfiles
на дві системи macOS та одну Linux (а точніше, Codespace). Дійсно дуже допомогло те, що в Chezmoi є шаблони. Інакше я б все ще шукав власне рішення (та чомусь не маю єдиного вірного варіанту шаблонізатору.)
Приклад розбіжності: на macOS в мене налаштований підпис комітів з GPG. В Codespace підпис теж працює, але іншим способом: агентом, який був наданий оточенням. З шаблонами це дуже легко обійти: {{ if eq .chezmoi.os "darwin" }}
та так далі.
Була проблема — в Codespace все відбувається повільніше. Розгортування dotfiles
(а саме, встановлення залежностей) триває декілька хвилин. Це не так погано для користування, але жахливо для розробки, коли нічого ще не працює. Тому знайшов образ, який використовують Codespaces та написав скрипт, щоб запускати все локально в Docker, приблизно отак.
Причому з Chezmoi в мене система, де я можу внести правки з будь-якої з систем та розповсюдити їх на інші через git. Якби не було, то файли забруднюються локальними змінами та потім вже доведеться наново все збирати. (Як в мене вже траплялося.)
Для спрощення конфігурації корисно розбивати файли на менші, там, де це можливо. Сьогодні дізнався, що в .gitconfig
теж є механізм include. Так само в конфігурації оболонки. Зокрема це дозволить обмежити використання шаблонів, та залишити незмінні частини “чистими”. Бо в шаблонів є значний недолік: вони зазвичай псують підсвітку синтаксису та інші інструменти редактору.
23.07.2024
Chezmoi - менеджер для dotfiles
Знайшов Chezmoi - гарну утиліту для керування dotfiles. Це, порівняно зі згаданим в коментарях stow, цілий комбайн, але мені то подобається, бо розвʼязує майже всі потреби, які в мене були. Одну не розвʼязує — це як зробити свої dotfiles достатньо публічними для публікації. Тому цього робити не буду.
В Chezmoi трохи дивна структура директорії: замість того, щоб мати перелік файлів чи інструкцій, копіюється кожний файл, який є (окрім спеціальних). Це, коли звикнеш, спрощує розуміння, як на мене. Треба файл - додаєш файл. Ще цікаво, що Chezmoi не робить посилання, а копіює файли.
Далі, дуже важливо, що файли можуть бути шаблонами. Причому Chezmoi написаний на Go, тобто це шаблони Go, звичні мені за Hugo (та й за роботою теж.) Для шаблонів заготовано чимало функцій, включаючи інтерактивне введення значень та навіть читання з 1Password та інших менеджерів. Також шаблонами можна відокремити конфігурацію для різних машин — це теж важливо. Причому, до речі, Chezmoi має підтримку всіх можливих платформ, включаючи Windows.
Є механізм завантаження додаткових файлів. Навіть цілий репозиторій Git можна завантажити та розгорнути. Така потреба виникла в мене відразу.
А для складніших операцій є й підтримка скриптів. Куди ж без неї. Скрипти можуть бути одно- або багаторазовими, а також містити шаблони.
Добре, що Chezmoi розрахований на повторні запуски — є навіть особливий синтаксис chezmoi update
для оновлення репозиторію та застосування змін в одну команду. Бо dotfiles
гарні тільки тоді, коли їх можна тримати актуальними.
Поки мені все дуже подобається. От тільки доводиться наводити лад у конфігураційних файлах, бо трапляються шматки, якими вже років 10 не користуюсь.
22.07.2024
Як я робив Linux на Windows у 2010
З 2016 року в Windows вбудована WSL - можливість встановити Linux та працювати з ним одночасно з Windows: прямо відкрити консоль, запускати сервіси — та все не виходячи з Windows. Я коли це побачив, відразу знав, що це круто — бо сам робив таке саме ще 6 років тому за допомогою продукту під назвою colinux.
Не знаю, скільки людей користуються таким підходом зараз, бо обставини, безумовно, змінились. Зокрема, у 2010 Linux на ноутбуці був обʼєктивно неповноцінним. Найгірше то те, що не було нормального рішення для сну: або вимикати ноутбук повністю, або поступово витрачати батарею та гріти рюкзак на “неглибокий” сон. У Windows був режим Hibernate, який зберігав стан памʼяті та вимикав живлення.
Але… на Windows було надзвичайно складно працювати з Ruby. Багато бібліотек мали помилки, або просто не підтримували цю платформу. До того ж Ruby потребує командного рядка, а в Windows з цим історично погано. (В порівнянні, стек Apache + MySQL + PHP був цілком надійним.) Тобто потрібний був компроміс.
Щоб запустити Linux, можна було взяти VirtualBox. Але, в такого рішення був ряд недоліків: машини VirtualBox працювали в ізоляції, мали окрему файлову систему, мусили бути запущені вручну щоразу. Не те, чого хотілось. Тоді знайшов coLinux - цей продукт запускав ядро Linux як сервіс Windows - автоматично, у фоні, та з доступом до тієї самої файлової системи.
От тільки чого не було, так це зручного терміналу. Доступ до Linux відбувався по SSH через PuTTY. Рішення трохи неповноцінне. Натомість дізнався, що графічна система Linux - X11 - взагалі є клієнт-серверною, та здатна працювати навіть через локальну мережу. А для Windows теж є сервер X11: Xming. Через підключення до нього я запускав Rxvt як графічний емулятор термінала на Linux, а вікно зʼявлялося на Windows та чудово себе почувало з такими зручностями як буфер обміну. Так само запускав й GVim: так, Vim є й для Windows, але ж під Windows він не мав би доступу до робочого оточення.
Нарешті, зазначу, що з появою в житті MacOS у всьому цьому навідріз зникла потреба. Залишились тільки спогади.
21.07.2024
Інцидент з Crowdstrike: операційне фіаско
Не люблю коментувати про поточні події, але в історичному інциденті з Crowdstrike є чому повчитись.
Досить швидко знайшли причину помилки — причому, як сторонні дослідники, так і в самій компанії. Дехто привʼязав її до вад мови C++. Для мене це рефлексія програмістів на класичну тему “чия мова краще.” Хоч в C++ є свої недоліки, але я ще не зустрічав мови, в якій не буває помилок. Особливо на стику системної інтеграції. Для мене наявність помилок в програмі — неуникна реальність.
Що обурює мене в цій всій історії, це як збірка з критичною помилкою опинилася на 8.5 мільйонах компʼютерів? На жаль, це питання не таке прозоре, а відповідь не така проста, як “переписати все на Idris”. Та й взагалі, операційні недоліки не виправиш за один день з пресрелізом “сорян, передеплой, будь ласка”.
Втім, коли у нас трапляються схожі ситуації (тобто критичні помилки в продакшні — на щастя, не в тому масштабі та не в тих скрутних обставинах), ми шукаємо не якої особливості не вистачає Ruby чи Go для уникнення таких помилок, а який процес покращити, щоб помилка була виявлена якнайраніше? Технік безліч — від юніт-тестів до канарейкового розгортування.
20.07.2024
Логи та топологія
Логи мають дещо спільне з бекапами: вони цінні, коли можеш їх прочитати, а не тільки збираєш. Після першої версії інструменту перегляду журналів для CodeDeploy багато про це думаю.
Ну, скажете ви, прочитати журнал — це тривіально. На жаль, тільки поки топологія проєкту тривіальна. З кожним новим сервісом зʼявляються проблеми. (Навіть не буду про те, що логи мусять сходитися в єдину базу — це, сподіваюся, зрозуміло.) Стає складно зрозуміти, який журнал чого стосується: логічний розподіл сервісів не завжди відповідає фактичному набору журнальних потоків. Тобто щоб визначити потрібний журнал, потрібно знати подробиці реалізації, а не тільки мати уявлення про загальну архітектуру.
Типове використання журналу: дослідити причину несподіваної ситуації. Для цього потрібна можливість передивлятися журнали за графом архітектури: від того сервісу, де ситуація трапилась, до його залежностей, і так далі. З одного боку, тут доречно впровадити APM, тобто журналювання запитів з відстеженням сліду через сервіси. З іншого, мої проблеми це не розвʼязує. Уявимо ситуацію: база даних була перевантажена, тому не змогла прийняти запит від сервісу. Тут мене цікавить не сам запит, а що відбувалося в базі на той час.
Поки не знайшов інструменту такого “топологічного” перегляду журналів. Та ще й AWS CloudWatch - не дуже зручна база. Фактично вони пропонують лише два способи перегляду: або конкретний потік (гарно тільки коли ти точно знаєш, яка копія сервісу цікавить), або пошук запитом Log Insights - це хоч і гнучко, але писати щоразу запит дуже втомлює.