Стендап Сьогодні
Що я зробив, що я хочу зробити, і що це все значить.
Повсякденні здобутки в форматі стендапу.
Детальніше в статті
Підписатись на RSS
📢
Канал в Telegram @stendap_sogodni
🦣
@stendap_sogodni@shevtsov.me в Федиверсі
05.04.2023
Заміна DNS на власний — коли це потрібно та як це зробити
Якщо ваша бізнес-логіка спирається на DNS, то цілком логічно мати тестове середовище, де DNS контрольований. Тоді можна перевірити різні випадки — який запис є, якого немає, що за значення повертає і так далі. Але, DNS здається таким глибоко системним сервісом, що торкатись його здається неможливо (хіба що /etc/hosts
міняти, але то дуже обмежено.)
Насправді зробити свій DNS-сервер досить нескладно; принаймні на Go для цього є проста бібліотека, з якої можна зібрати свій простий сервер (ось приклад). Все, що вам потрібно — це приймати деякі DNS запити та відповідати на них; решту можна або не обробляти, або передавати іншому серверу (як 99.9% DNS серверів в інтернеті й роблять.)
Я колись давно робив сервер, що перекриває DNS записи за розкладом. Така була міра обмеження відволікань. Досить ефективно працює, до речі — особливо якщо не зробиш можливість вимкнути. Бо пізніше я перейшов на більш функціональний Pi-hole, так от там вже можна було припинити блокування через вебінтерфейс. А зараз взагалі цього не роблю.
Залишається, щоправда, останнє питання — як підʼєднати той сервер до вашої тестової системи? Тут проблема, бо системний клієнт DNS не дасть поміняти порт, до якого він буде звертатись — домен чи IP - будь ласка, а порт тільки системний. Я так розумію, що то заради безпеки, хоча хтозна. В інших клієнтах можна вказати порт — наприклад, dig -p 5353
, або якщо клієнт на Ruby.
Якщо ж треба саме замінити саме системний DNS, то заміну доведеться розташувати в Докері; тоді можна відкрити стандартний DNS порт (а це 53, до речі). Взагалі я б такі тести тільки в Докері й робив би; створюєш собі docker-compose на всі сервіси та тестуєш в повній ізоляції.
04.04.2023
Замість списку задач краще вже зробити те, що треба
Останнім часом мені здається, що накопичення задач — це спосіб прокрастинації. Прокрастинація тут в тому, що за великою кількістю задач ховаються ті самі страшні справи, які нам в першу чергу треба робити, але ніяк не хочеться. Для таких задач зазвичай і списку не треба, бо вони про себе нагадують самі. Але замість того, щоб зробити та забути, ми будемо займати час будь-чим інше — продуктивним чи не продуктивним.
Тому придумав сьогодні систему оцінювання задач по квадрантах. За однією шкалою — наскільки хотілося б щоб задача була виконана. За іншою — наскільки не хочеться цього робити.
В першу чергу треба робити те, що дуже не хочеться, але буде найприємніше бачити зробленим. За моїми спостереженнями, це є задачі, що й приносять найбільше задоволення, гордість та користь, задля яких ми все це і робимо.
Далі можна робити те, що приємно й зараз й принесе радість потім (але воно зазвичай робиться само собою.) Потім — що приємно зараз, але потім користі не буде (це всілякі розваги). І нарешті — те що і не приємно, і користі не буде, ми не робимо (бо таке насправді рідко приходить на ум).
Тож ідея моя ось така. Записати на аркуші 3 найбільш болючі та важливі задачі. Робити їх; поки не зробиш, фокус має повертатись на них постійно. Поповнювати список за ходом виконання. Повторювати до досягнення душевного комфорту.
03.04.2023
Стрес-тест як дослідження системи
На першу чергу, метою стрес-тесту є обчислення деяких метрик. Насправді на мою думку, обчислення метрик — це тільки початок роботи. Мені більше цікаві пояснення цих метрик, та уявлення про роботу системи, яке можна з них отримати. Для мене головне питання стрес-тесту — у що він упреться?
Що я маю на увазі. Щоб дізнатись, на що здатна система, треба завантажити її на 100%. Але, в розподілених системах (якою є навіть додаток з його базою даних) навантаження ніколи не накладається рівномірно — обовʼязково є вузьке місце. Після отримання результатів стрес-тесту необхідно знайти це місце, а далі найцікавіше — прибрати вузьке місце, та спробувати тест знову. Повторювати до тих пір, поки не буде чітко знайдено місце, яке неможливо “розширити” (та тому причина) - воно і є справжнім обмеженням всієї системи.
Наприклад, протестували API. Перевіряємо — де 100%? Якщо ніде немає — недовантажили мережу. Треба більше запитів. Зробили більше запитів — бачимо, база натужилася. Знайшли N+1 запит — виправили. Нарешті, тепер бачимо 100% CPU додатка. Якщо припустити, що в додатку немає що оптимізувати, то тепер ми маємо справжню картину. Але можна й взяти профайлер, та продовжувати вже на рівні коду — всередині додатка теж буде вузьке місце.
Без цих дій, на мою думку, стрес-тест власної системи — марна витрата часу. Це як розганяти машину на першій передачі — якесь число ми отримаємо, але хіба воно буде корисне? Тільки як показник “як все було погано”.
02.04.2023
Короткий огляд KVM-засобів для ігор
В мене ігровий ПК стоїть у вітальні, під телевізором, бо працює також і медіацентром. Там зручно грати у “консольні” ігри, бо вони розробляються для гри з дивану — мабуть, найголовніше в цьому великий масштаб інтерфейсу, хоча розташування камери (віртуальної) теж важливе. Технічно з дивану можна грати в будь-що, але якщо стрілялки з клавіатурою та мишею ще хоч якось прийнятно, то стратегії зовсім тяжко.
Тому захотів я підʼєднати цей ПК також і до робочого місця. Тобто влаштувати собі [KVM-перемикач] між робочим ноутбуком та ПК. Тоді можна спокійно собі сидіти та грати хоч в Cyberpunk, хоч в який-небудь The Great War: Western Front, яка вийшла два дні тому
Мій новий монітор Sony inzone M9 як раз підтримує KVM, тож перше що я хотів зробити, це банально протягнути HDMI та USB від ПК до монітора. Але дріт цей буде йти з кімнати в кімнату та мати довжину метрів 15-20; при цьому звичайний HDMI (та і USB) вже не підійде через втрату сигналу, тому потрібний так званий “KVM extender”. Такі є на основі кабелю Ethernet, а є оптичного кабелю (з максимальною довжиною — хвилиночку - 40 км!) Проблема — це дорого; від $100 за варіант з 1080p, до $400 та вище за оптику та 4K. До того ж “апаратність” тут досить умовна, бо пристрої подовжувача є по суті компʼютерами. HDMI складний протокол. На моєму досвіді, “апаратне” рішення ніяк не гарантує відсутність проблем, але практично гарантує, що якщо вони виникнуть, то ти їх не розвʼяжеш.
Для будь-якого програмного KVM перше та наголовне — це встановити звʼязок через дріт. Без всякого Wi-Fi. Інакше затримки сигналу гарантовані. На такий рівень, щоб реально хотілось грати через мережу, а не напряму, можна розраховувати тільки з дротовим підключенням. Та й взагалі, в домашній офіс зі постійним робочим місцем Ethernet треба тягнути обовʼязково.
Synergy, а також її нащадки Barrier та Input Leap - хоч називаються KVM, але дають розділити тільки клавіатуру та мишу; не відео. Тож для моїх цілей не підходить - Synergy для випадку, коли у вас поруч два монітори з різними системами, та потрібно ними керувати.
Steam Remote Play - працює непогано, але тільки з іграми Steam. Колись я грав в Elden Ring на відстані у 200 км, та навіть виходило — аж до першого серйозного боса — хоч якість зображення була ганебна. Втім з кімнати в кімнату Remote Play працює добре.
Parsec - тільки його знайшов, але оце KVM що справді мене влаштовує! Якість зображення на висоті (до речі, використовує сучасний кодек H.265, який апаратно кодується та декодується як на ПК, так і на ноуті). Затримок не має. Поводить себе як нормальний додаток macOS. Підтримує будь-які ігри, бо взагалі показує весь віддалений екран. Parsec безплатний для приватного використання. Так що раджу спробувати, дуже приємне рішення.
Одним словом, поки налаштував собі Parsec та він, схоже, вміє все, що я хочу. Не треба купувати коштовні пристрої та свердлити стіни. Успіх!
01.04.2023
Граматики PEG для розбору документів
Взагалі якщо вже потрібно розібрати складні документи, такі як CSS, то варто взяти генератор парсерів з граматики, тобто PEG. Принаймні, я б це так робив.
Чому PEG? Тому що думати про мову в декларативному контексті (граматиці) простіше, ніж в імперативному (коли треба писати свій парсер.) А також код, який вона генерує, зазвичай простіше алгоритмічно, ніж код розбору з регулярними виразами. Граматика PEG описує структуру мови; весь документ складається з деяких частин або виразів, вони розбиваються на менші вирази, і так далі до мовних примітивів — констант, ідентифікаторів, ключових слів.
В мене є досвід розбору власної мови на Go. Там для цього є бібліотека Pigeon. Мені подобається, що парсер на Pigeon не просто розбирає текст документа в синтаксичне дерево: натомість ти задаєш код, який буде викликатись на кожний елемент цього дерева. Так можна не тільки відразу будувати семантичну структуру (таку, що складається з обʼєктів бізнес-логіки), а й в деяких випадках взагалі відразу робити обчислення та робити результат.
В Ruby теж є схожі бібліотеки, наприклад Treetop або Raabro. Вони не дуже відомі, бо власні мови нечасто зустрінеш. Але при цьому їх можна знайти в залежностях гемів, які нам добре знайомі — наприклад, sidekiq-cron використовує Raabro для розбору виразів Cron.
PS: нещодавно оновив Hugo, та він, як виявляється, змінив порядок постів в RSS. Тому стрічка стала містити 30 перших, а не останніх постів, тож фактично перестала оновлюватись. Здається, тепер виправив.
31.03.2023
Як я зробив css_parser у 3 рази швидше
Є така хороша бібліотека для Ruby - css_parser. З 88 мільйонами завантажень, це вірний вибір для розбору CSS з середовища Ruby. Зазвичай вона працює добре, але ми виявили, що не для будь-яких документів. На деяких вхідних документах швидкодія падала безнадійно. Ну як — безнадійно? Насправді надія є, можна взяти та зʼясувати, що не так — адже код відкритий.
Так я і зробив; головні покращення можна подивитись в цьому коміті. Сьогодні на них натрапив, та хочу нарешті повернути ці зміни в головну версію бібліотеки. Але поки розкажу, що там помінялось та як я це знайшов.
Власне, головна проблема оригінального коду була в використанні регулярних виразів. В більшості випадків вони працювали нормально; але якщо тільки в документі присутня велика кількість пробілів, як інколи трапляється, то маємо вищезгадане уповільнення — замість частки секунди розбір тривав хвилини.
Але регулярка не робила нічого магічного; вона розділяла вираз CSS на властивості — крапкою з комою, а потім на імʼя та значення — двокрапкою. Це досить легко зробити за допомогою простіших методів String#split
та String#index
.
Далі за допомогою профайлера RubyProf та його режиму відстеження виділення памʼяті я переробив код циклу так, щоб уникнути виділення памʼяті повністю. (Щоб побачити, що проблема в регулярці, теж був потрібен RubyProf, але в більш звичному режимі відстеження часу виконання.)
Ці зміни не тільки покращили швидкість розбору в 3.5 рази та використання памʼяті в 3 рази, але й уникнули тих випадкових проблем з регулярками, з яких все починалось. Як бачите, проблема була не в тому, що Ruby - повільна мова, а в тому, що підхід обраний неоптимальний. Регулярні вирази - потужний інструмент, але ж потужність приходить з ціною; для простих потреб треба брати прості, явні операції на рядках.
30.03.2023
Як робиться аналітика з Plausible
Вже кілька разів згадував, що для вебаналітики обрав сервіс Plausible. Це радикально простіший сервіс, ніж Google Analytics або все що на них схоже. Головна різниця - Plausible не будує портрета користувача. Це не тільки простіше, а й береже вашу конфіденційність. Сеанси відстежуються в межах доби, і це найдовша “памʼять” про вас в Plausible. (Сеанс потрібний, щоб підрахувати унікальних користувачів, тривалість, вхідні/вихідні сторінки.) Також відзначу, що в них компактний скрипт та дуже простий API.
При цьому в Plausible можна відстежувати не тільки сторінки, а й цілі — я писав як відстежую відвідувачів RSS. В Сінтрі ми також відстежуємо екрани мобільного додатка — у кожного екрану свій URL.
З цілей та інших метрик можна побудувати воронки. У власній табличці, бо вбудованих інструментів для цього немає. Різниця в тому, що воронка будується статистично, бо шляху кожного конкретного користувача Plausible не знає. Але на практиці воронка як воронка, дає побачити, які кроки важкі, де люди відвалюються.
До речі, про кроки. Типовий підхід до дата-аналітики (як я бачив) - то скидати всю активність до купи в базу даних, а потім вже витягувати з неї необхідні метрики. Ну, наприклад для Сінтри можна було б записувати в Google Analytics подію на кожну додану витрату, а потім робити запити на кшталт “користувач, у якого понад 1 витрату = спробував; понад 10 витрат = почав користуватись”.
Ми так не хочемо, тому натомість ми на своєму боці перевіряємо досягнення порогів, та відправляємо в Plausible остаточні події: “спробував”, “почав користуватись”. Вони не привʼязані до користувача, тому ми можемо тільки побачити кількість таких подій. Але все одно можна підрахувати, що за тиждень 10 реєстрацій, 7 спроб, та 5 початкових користувачів, та цього достатньо, щоб зрозуміти, де проблеми. Виходить більше роботи з боку додатка, але це не є проблемою, коли й додатком, і аналітикою займаються одні й ті самі два хлопці.
29.03.2023
Абсолютний мінімум самоменеджменту
Сьогодні був цікавий день; я ревьював 380 пул реквестів. Це через те, що більш як місяць тому припинив це робити, бо сфокусувався на іншій роботі. З одного боку, нікому так не раджу робити. З іншого, радий що все ж таки все продивився, та що тепер можу повернутись до щоденного режиму.
Щоб продовжити вчорашню тему про керування часом, думав над абсолютно необхідним мінімумом, який треба собі забезпечити — не заради якоїсь “продуктивності”, а просто щоб не жити в “режимі білочки”, тобто не стрибати без кінця від одного негайного діла до іншого.
-
Відокремлення “вхідного кошика” та його регулярне опрацьовування. Вхідний кошик — то місце для всього нового. Головна причина цьому: більшість “нового” це інформаційне сміття. Щоб не жити у смітті, потрібно свідомо виділяти те, що потребує уваги, та позбавлятись всього іншого.
-
Система виконання (а також сортування за пріоритетом та, можливо, планування.) Найпростіша то є список задач (або голова). Всього відразу не зробиш. Система виконання тримає все, що треба зробити, та — головне! - дає гарантію, що воно буде зроблене. (Або свідомо відкинуте.) Без такої системи все навколо починає нагадувати про задачі, і все одно багато забувається.
-
Календар потрібний для відстеження подій, запланованих на дату та час. До того сучасний календар підтримує звʼязок зі співучасниками. Напевно, тому з календарем зазвичай у всіх все добре - діє соціальний тиск. Тільки додам, що календар не є системою виконання; в першу чергу, тому, що це місце для подій, що відбудуться точно та в певний час, а задачі не відбудуться, поки ми їх не зробимо.
-
База знань зберігає все, що не є задачею або подією. Головна функція такої бази — це звалище всього, що нам зараз не потрібно, а потім, може, ще й згодиться. База знань звільняє свідомість та робочий простір.
PS: 🧑🎨 Unsplash не оцінив мої вертикальні шпалери, тож доведеться шукати інший фотохостинг. Та ще такий, щоб було відомо, що на ньому такі шпалери шукають.
28.03.2023
Bullet journal: постмортем
Настав час для новин по самоменеджменту з блокнотом. Що ж, система вмерла — десь на кінець другого місяця, хоча здригалася ще до середини березня. Робимо постмортем.
-
Що працює добре. Блокнот; кому як, а мені приємно писати ручкою (лінером) по паперу. Регулярна обробка вхідних куп (пошти, нотаток тощо) - без цього я взагалі гублюсь. Але… задачі з вхідних куп треба заносити в список задач. Якому ти довіряєш. На цьому й починаються проблеми.
-
Причина смерті — задач стало надто багато. До речі, окрім задач на день я ще вів окремий перелік проєктів а-ля GTD - туди потрапляло все, що за один підхід не зробиш. Довгий час задачі, записані на день, виконати виходило, а копати список проєктів — ні. Потім й на день стало кілька десятків задач. Спостерігаю, що в мене задач завжди стане більше, ніж я фізично можу виконати.
-
Минулого тижня слухав книжку Four thousand weeks: Time management for mortals. Вона як раз про те, що сучасне життя вимагає надто багато — більше ніж реально зробити — тому спроба все встигнути чи побудувати систему, яка це допоможе зробити — даремна. Натомість книжка радить усвідомити, що час обмежений, та фокусуватись на тому, що ти можеш зробити, а не на ідеалістичному списку задач.
-
На цей час спробую використати систему Final Version Perfected. Її сила як раз в тому, що вона здатна працювати з необмеженим списком задач; найменш важливі з них просто залишаються незробленими та з часом їх викреслюють. Тобто визначення пріоритетів та виконання поєднані в один процес. Та, головне, немає тяжкого для мене аспекту відмови від чогось; навпаки, в системі FVP ти обираєш, яку справу зробиш наступною, надаєш їй ваги, а це важливо для позитивного сприйняття всієї системи.
27.03.2023
Паралелізація запитів в Ruby
Хочу висловити похвалу моделі одночасного виконання в Ruby, а саме, класу Thread. Ruby так зневажливо відносять до повільних мов, що яка вже там одночасність! Тут же ж навіть багатопотоковості немає. (До речі, справжня багатоядерна паралелізація в Ruby 3 теж вже є, з класом Ractor).
Насправді є сценарій, в якому одночасне виконання дуже допомагає, та він всім нам добре відомий — це звертання до мережевих ресурсів. Будь то запити до API, чи завантаження сторінок, чи надсилання листів по SMTP - всілякі операції через Інтернет можна робити паралельно в декількох потоках, бо під час запиту програма все одно стоїть та чекає відповіді. (Єдине, що треба мати на увазі — не робіть з потоків звертань до бази даних, бо це вичерпає пул підключень. Або пул треба збільшити, або роботу з базою винести з потоку.)
# Паралельне завантаження сторінок
urls.map { |url| Thread.new { Net::HTTP.get(url) } }.map(&:join)
Так на минулому тижні мені вдалося замінити процес, що займав дві години, та опитував кожний ресурс послідовно, на паралелізоване рішення, якому потрібно двадцять хвилин. І це мені поки боязно робити надто багато запитів — можливо, в майбутньому зробимо ще швидше.
Для більш поглибленого використання можливостей одночасності можу порадити гем concurrent-ruby. В ньому реалізовані класи для всього, що можна собі уявити. Я, наприклад. завжди маю на увазі пул тредів для обмеженої паралелізації.