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

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

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

03.12.2022

Скрипт для повідомлення про наявність звʼязку на основі Firebase

🔥🌚🌝 Скрипт для повідомлення про наявність звʼязку написаний.

Спочатку години три робив реалізацію на GitHub: маркер наявності звʼязку записував у файл, а перевіряв регулярним процесом GitHub Actions. Складність в тому, що на роутері дуже обмежене середовище, і там немає ані git, ані навіть команди base64. Можна поставити флешку та розгорнути повноцінну систему з пакетами та іншим, але не хочеться — в мене поганий досвід використання флешок як постійно увімкнений диск. Доводилось використати API, але з ним все теж не так просто. Я все ж таки знайшов, як це робити, але залишу розповідь на інший раз, бо рішення вийшло таке складне й незграбне, що продовжувати не хотілось.

Натомість пан Олексій нагадав, що також можна зібрати таку систему на Firebase. Та дійсно, Firebase розв’язує головну проблему з інтеграцією в роутер — надає можливість створити хмарну функцію, яку можна викликати простим HTTP запитом, не ускладнюючи авторизацією та іншим. Та до того ж має просту у використанні базу даних Firestore - якщо доступ до неї здійснюється тільки з бекенду, то не потрібно ніяких правил безпеки.

Як щодо Slack, то насправді не так все складно — аплікація створюється тут, а далі те, що нам потрібно, називається Incoming Webhook і дозволяє постити в слак максимально простим запитом на фіксований URL: {"text":"Hello World!"}.

Скрипт для Firebase ось тут, і так — весь код цієї системи вміщується в один файл. Розгорнути його можна абсолютно безплатно, а з боку домашньої мережі потрібен будь-який пристрій, що робитиме запити HTTP GET.


02.12.2022

Як автоматично стежити за відсутністю звʼязку вдома

📶❌📢 У звʼязку зі повторюваною відсутністю звʼязку, хочу зробити такий собі інструмент, щоб повідомляв команду про те, що я їм зараз поза зоною досяжності. Надихався цим постом , але там тільки віджет, та до того ж він вимагає наявності статичного IP. Поки я на етапі планування. Початкова ціль — повідомляти в слаці, якщо в мене немає домашнього інтернету (бо я вже дванадцять років працюю з дому, до речі.)

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

В мене роутер ASUS, оснащений прошивкою Merlin. З таким роутером не потрібний компʼютер, щоб подавати сигнали — скрипт виконуватиме сам роутер. Звісно, середовище скриптів на роутері обмежене, і так само обмежене місце (хоча можна й флешку під’єднати.)

Тепер, куди відправляти сигнал? Та головне — як це зробити безплатно? Я беру звичний AWS, а саме AWS S3. На S3 можна відправити до 2000 безплатних запитів на запис в місяць. Цього цілком вистачить для того, щоб сигналити щогодини. Писати на S3 нескладно, хоча з Bash я цього ще не робив.

Нарешті, для перевірки статусу візьму AWS Lambda - тут достатньо безплатних хвилин виконання. Лямбда-функція повинна запускатись раз на годину, дивитись таймстемп файлу на S3, та, якщо він перебільшує годину чи дві, повідомляти в Slack.

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


01.12.2022

Cтворення великого контексту БД для тестів за допомогою пакетної вставки

🏭🚚🗄️ Сьогодні маленька порада для рубістів, а саме — як швидко створити багато записів в базі, особливо для тестів.

Якщо з локальною базою це може заощадити вам секунди, то з тестами на AWS Redshift - буквально хвилини. З Redshift доцільна така інтуїція: команда INSERT працюватиме однаково швидко для одного рядку та для багатьох — або краще сказати, однаково повільно. Хоча й на звичайній базі можна прискорити якісь аналітичні тести з купою записів.

Всі мають знати метод insert_all, який виконує ту саму команду INSERT для декількох рядків. Також варто знати, що, окрім того, він перевірятиме рядки на дублікати, а якщо цього робити не потрібно, то є метод “з наголошенням” insert_all!.

Багато хто також знає метод FactoryBot.create_list. Але він нічого особливого не робить, просто створює декілька записів в циклі.

Тож як подружити insert_all та FactoryBot? Якось так: Product.insert_all(FactoryBot.build_list(:product, 100).map(&:attributes)). Тобто, готуємо записи без зберігання, потім беремо від них атрибути й вставляємо однією командою.

Такий метод не створюватиме асоціацій, тому їх доведеться створювати окремою командою.


30.11.2022

Перші враження від PagerDuty

🚨⚠️⏰ Перші враження від PagerDuty: це не магічне рішення всім проблемам моніторингу та підтримки.

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

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

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

Коротше, PagerDuty ще треба налаштувати на ситуації “кинути всі справи та виправляти”, а за CloudWatch доведеться й далі спостерігати, але іншими способами.


29.11.2022

Як ефективно програмувати, коли немає звʼязку?

🌑🔦👩‍💻 Як ефективно програмувати, коли немає звʼязку? Головна проблема цих днів — відсутність швидкісного інтернету. Ноутбука вистачає на багато годин. Але ж звʼязок при відсутності електрики швидко псується. Дротовий інтернет не працює без роутерів, мобільні мережі перенавантажуються, бо всі разом перестрибують на них.

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

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

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

Хоча я розумію, що інколи емуляція не підходить. Тоді можна знайти альтернативну роботу — наприклад, написання тестів для коду, що вже існує (бо тести ж мають працювати без зовнішніх залежностей?). Або виправлення правил лінтера. Для Terraform є такі вичерпні лінтери на кшталт tfsec, що я впевнений, що ваша конфігурація їх ще не проходить. :)

Додатковий фактор — документація. Тут тяжко без інтернету, знаю. Базову документацію зручно тримати локально — я вже багато років користують Dash. Туди, до речі, можна завантажити й документацію до окремих пакетів. І навіть топові запитання StackOverflow, хоча це мені мало допомагало.

Також треба згадати, що на більшості сучасних мов ті пакети, що є залежностями, вже є завантаженими локально, і читати їх код можна без GitHub. В Ruby є зручна команда bundle open, але знайти місце розташування залежностей завжди можна вручну.

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


28.11.2022

Метод фітнес-трекера в продуктивності, щому це працює для мене

🚶‍♂️📆🐝 Продовжуючи тему з плануванням, якщо я вже її зачепив. Як я вже казав, системи в мене не дуже працюють. Розкажу, що працює.

Найбільш безперервне явище в моєму житті, вже 9 років — то виходжування норми кроків на фітнес-трекері (або тепер — калорій). Пропускаю я не більше як день щопівроку. Це само по собі дуже важливе, хоч і базове досягнення. Але воно наштовхнуло мене на цілу теорію кермування життям. Чому фітнес-трекер так добре працює?

Останнім часом я багато обмірковую, як цю “теорію фітнес-трекера” застосувати до інших галузей життя.

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


27.11.2022

Мій досвід тайм-менеджменту. GTD та інше.

В мене складні відносини з плануванням. З одного боку, методологія Getting Things Done перегорнула мені життя, і я досі вважаю її ґрунтовною для впорядковування власного життя. З іншого боку, це було років 15 тому, і за весь цей час GTD в мене так і не прижилась.

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

Можливо, що буддизм має правильну відповідь. А саме: хапатись і намагатись керувати життям — то є дукха; натомість треба пливти за течією. Власне, останні роки я нічого не планую детально, а просто намагаюсь робити крок за кроком до мети. Таке собі “планування методом A*”. Це не завдяки буддизму, а через втрату довіри до систем організації.

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


26.11.2022

Як поставити зірку в GitHub через скрипт

⭐🤩💫 Фух, нарешті розставив зірочки першим репозиторіям, якими користуюсь.

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

Але — як авторизувати його? Спочатку я хотів зробити це з Personal Access Token, які можна створити вручну через вебінтерфейс. (До речі, ця можливість дуже прихована. Ось пряме посилання, якщо не хочете пройти квест.) А ще нещодавно зʼявились так звані “fine-grained tokens”, якими можна обмежити доступ токена. Я думав, що то ідеальне рішення.

Тільки воно не працює. Виклик “зіркового” API з персональним токеном заборонений. Це удвічі дивно, бо для fine-grained tokens можна обрати й доступ на запис до зірок. 🤷

Тобто (принаймні на сьогодні) для цього API треба робити OAuth2. Це легко, але не зі скрипту. Зазвичай авторизація OAuth в скриптах вимагала від кожного користувача створення власної аплікації з власними ключами — бо нормальний OAuth вимагає серверної частини для зберігання секретів, а в скрипті я б робив “фейковий” сервер.

Тому я був дуже радий дізнатись, що GitHub має особливий режим авторизації для скриптів - Device flow. У цьому режимі, фактично, GitHub сам виступає серверною частиною, а скрипт містить тільки несекретний ID аплікації, а отримує готовий access token.

…Додатково сьогодні встановив на компʼютер з Windows ще і Ubuntu (бо потрібен “залізний” Linux для деяких операцій). Ця процедура стала набагато простіше, ніж останнього разу (багато років тому.) Єдине, що для встановлення на систему з UEFI треба було створити флешку програмою Rufus.


25.11.2022

Як дістати перелік залежностей для проєктів на Ruby, JavaScript, Golang

💎☕🐹 Закінчив зі збором залежностей для всіх трьох моїх головних мов - Ruby, JavaScript, Golang. Виявилось, що для Ruby було складніше за все.

В JavaScript залежності перелічені в файлі package.json, який як звичайний JSON легко прочитати. Далі є API npm.js https://api.npms.io/v2/package/:packagename, звідки дізнаємось домашню адресу пакета. (До речі, і цей API, і API RubyGems відкриті, бо всі їми користуються кожного разу, як встановлюють пакети.)

В Go залежності містяться в файлі go.mod. (Принаймні, в сучасному Go, бо раніше було декілька альтернатив, а зараз все стабілізувалось.) Файл go.mod нестандартного формату, але не складніше, ніж Gemfile.lock. До того ж оскільки в Go назва пакета — це адреса його репозиторію, то ці адреси ми дізнаємось безпосередньо.

Залишилось трохи причепурити та можна випускати у світ.

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


24.11.2022

Почав проєкт для автоматичного виставлення зірок на GitHub

😺⭐💎 Через відсутність світла робота не дуже йде. Почав як вправу маленький проєкт, який давно крутився в голові: GitHub Autostar

В чому суть. Всі ми любимо оцінювати проєкти на GitHub за кількістю зірок. Але ж хто ті зірки ставить? Я сам нечасто про це згадую. Тож виходить дивна асиметрична оцінка.

Щоб виправити цю ситуацію, я хочу зробити скрипт, який знаходить в моїх проєктах всі прямі залежності, що є на GitHub, та автоматично проставляє їм зірочки. Це можуть бути Ruby-геми, пакети NPM, модулі Go тощо. Навіть закладки чи нотатки. Так без зайвої ручної праці можна спрямити несправедливість оцінок.

Тепер трохи о реалізації: поки зробив прототип для Ruby. Спочатку ідея була така, щоб застосувати можливості Bundler для інтроспекції залежностей. Головна проблема з цим те, що щоб воно працювало, треба відтворити правильну версію Ruby для кожного проєкту, а також встановити всі залежності. (Також бракує документації по внутрішньому функціоналу Bundler.)

Тому схилився до статичного аналізу. Перша ідея: розбирати Gemfile. Але ж гемфайл — це фактично скрипт на Ruby, та хоч в гемфайлах зазвичай дотримуються визначеного формату, очікувати можна на все. Втім, знайти регулярками рядки вигляду gem "foo" досить просто.

Але потім нарешті роздивився структуру Gemfile.lock і знайшов там розділ, де перелічені прямі залежності проєкту (а саме, DEPENDENCIES.) Цей формат файлів створений для машинної обробки та — хоч він і не стандартний — прочитати його набагато легше, ніж Gemfile. Як результат, в робочих проєктах першим способом знайшлось 146 гемів, а другим - 150.

Після цього залишається звернутись до відкритого API RubyGems - https://rubygems.org/api/v1/gems/#{gem}.json та дізнатись домашню адресу кожного гему. А потім, перевірити, чи спрямована вона на GitHub.

Так отримав 128 репозиторіїв, що, порівняно зі 114 зірочками, що я поставив вручну за довгі роки користування Гітхабом, вже досить багато.

Наступні кроки — реалізація для інших мов, та пошук простого рішення для масової роздачі зірок.