Канал
У Льоні сьогодні
Нотатки архітектора систем та майстра на всі руки. Що я зробив, що з того вийшло, і що це все значить.
-
Мої рекомендації протоколу для RPC - HTTP, JSON, стійке підключення.
🏭🚂🏢 Мої стислі рекомендації по вибору стандарту RPC (дивлячись з боку систем на Ruby / Go.) Беріть JSON over HTTP, але обовʼязково — з використанням стійкого підключення.
Стійке підключення (таке, що зберігається на декілька запитів) важливе тому, що на встановлення підключення витрачається набагато більше часу, ніж на будь-яку “обгортку” запиту. Особливо якщо це підключення зашифроване — тобто практично завжди. Стійке підключення доступне в будь-якому клієнті HTTP.
Чому HTTP? Тому що інспектувати та тестувати такий API завжди буде найпростіше — інструментів безліч — браузер, термінал, спеціалізовані інструменти на кшталт Paw.
Чому JSON? Інтуїтивно здається, що, оскільки це текстовий формат, то він має працювати повільно. Але ні — завдяки тому, що JSON - це найбільш розповсюджений формат даних, та його парсери довершено оптимізовані. У моїх тестах JSON працював так само швидко, як і бінарні формати, принаймні на невеликих структурах даних. До того ж JSON легко читати та писати вручну.
Окремо раджу не брати gRPC, принаймні для Ruby. Бінарна частина gRPC має нескінченні складнощі з компіляцією, несумісна з Alpine, а також регулярно тече. Частина, що написана на Ruby, а точніше генерується, не слідує конвенціям. Так, gRPC дає можливість генерувати код клієнта та сервера з однієї специфікації, але ця перевага не перевішує всіх складнощів, що він з собою несе.
Щось складніше за JSON-over-HTTP раджу брати, тільки якщо потрібна величезна пропускна здатність. І тільки обмежено. Бо цим ви завжди втрачатимете простоту.
-
Як запостити файл на GitHub з мінімального середовища
😼🧙🐚 Величезний день роботи по дому — придбав перфоратор, повісив бойлер.
Розкажу, яким чином все ж таки можна запостити файл на GitHub з мінімального середовища (наприклад, на роутері).
Зовсім не обовʼязково для цього мати Git. Можна редагувати файли за допомогою API. Щоб зробити запит до API, достатньо мати
wgetабоcurl. Тіло запита — звичайний JSON, який можна побудувати шаблонним рядком.Тут є нюанс — зміст файлу має бути закодований у Base64. У мене на роутері утілити
base64не виявилось. Що ж робити? У моєму випадку потреби обмежені: треба було записувати в файл щось. Тож підготував текст, який вже був закодований в Base64.Далі — для зміни файлу, що існує, необхідно передати його поточний хеш. Це логічно, оскільки API має переконатись, що наша операція починається з відомого місця в історії Git. Цікаво, що при цьому не потрібно знати хеш коміту, а тільки хеш файлу. Легше всього дізнатись його теж через API.
Але як з відповіді цього API дістати значення, коли немає парсера JSON? Довелося парсити за допомогою регулярних висловів, а саме, командою
sed -E 's/.*"sha": "([^"]*)".*/\1/'. Такий вислів знайде у тексті JSON значення поляsha, та залишить у виводі тільки його.На останок, ще одна проблема: щоб створити новий коміт, файл треба поміняти. Можна було зробити взагалі просто: записувати у файл по черзі то текст, то порожнє значення. Поточний зміст файлу можна подивитись у тому ж API, що й
sha. Але я трохи перемудрив та потроху дописував у файл по 3 символи. Чому по 3? Тому, що у Base64 у кожному символі кодується 6 біт вхідного тексту, тобто 3 символи вхідного тексту — 24 біти — рівно діляться на 4 символи Base64.Якось так. Повний скрипт тут. Радий, що такі задачі зустрічаються хіба що заради вправи або забави.
-
Скрипт для повідомлення про наявність звʼязку на основі Firebase
🔥🌚🌝 Скрипт для повідомлення про наявність звʼязку написаний.
Спочатку години три робив реалізацію на GitHub: маркер наявності звʼязку записував у файл, а перевіряв регулярним процесом GitHub Actions. Складність в тому, що на роутері дуже обмежене середовище, і там немає ані
git, ані навіть командиbase64. Можна поставити флешку та розгорнути повноцінну систему з пакетами та іншим, але не хочеться — в мене поганий досвід використання флешок як постійно увімкнений диск. Доводилось використати API, але з ним все теж не так просто. Я все ж таки знайшов, як це робити, але залишу розповідь на інший раз, бо рішення вийшло таке складне й незграбне, що продовжувати не хотілось.Натомість пан Олексій нагадав, що також можна зібрати таку систему на Firebase. Та дійсно, Firebase розв’язує головну проблему з інтеграцією в роутер — надає можливість створити хмарну функцію, яку можна викликати простим HTTP запитом, не ускладнюючи авторизацією та іншим. Та до того ж має просту у використанні базу даних Firestore - якщо доступ до неї здійснюється тільки з бекенду, то не потрібно ніяких правил безпеки.
Як щодо Slack, то насправді не так все складно — аплікація створюється тут, а далі те, що нам потрібно, називається Incoming Webhook і дозволяє постити в слак максимально простим запитом на фіксований URL:
{"text":"Hello World!"}.Скрипт для Firebase ось тут, і так — весь код цієї системи вміщується в один файл. Розгорнути його можна абсолютно безплатно, а з боку домашньої мережі потрібен будь-який пристрій, що робитиме запити HTTP GET.
-
Як автоматично стежити за відсутністю звʼязку вдома
📶❌📢 У звʼязку зі повторюваною відсутністю звʼязку, хочу зробити такий собі інструмент, щоб повідомляв команду про те, що я їм зараз поза зоною досяжності. Надихався цим постом , але там тільки віджет, та до того ж він вимагає наявності статичного IP. Поки я на етапі планування. Початкова ціль — повідомляти в слаці, якщо в мене немає домашнього інтернету (бо я вже дванадцять років працюю з дому, до речі.)
Як дізнатись, що інтернету немає, якщо ззовні до роутера неможливо під’єднатися? Доведеться використати метод “канарки в шахті” - тобто сигналу, який подаватиме роутер, щоб зазначити, що він має підключення. Інший, зовнішній компонент має перевіряти наявність сигналу та робити висновки.
В мене роутер ASUS, оснащений прошивкою Merlin. З таким роутером не потрібний компʼютер, щоб подавати сигнали — скрипт виконуватиме сам роутер. Звісно, середовище скриптів на роутері обмежене, і так само обмежене місце (хоча можна й флешку під’єднати.)
Тепер, куди відправляти сигнал? Та головне — як це зробити безплатно? Я беру звичний AWS, а саме AWS S3. На S3 можна відправити до 2000 безплатних запитів на запис в місяць. Цього цілком вистачить для того, щоб сигналити щогодини. Писати на S3 нескладно, хоча з Bash я цього ще не робив.
Нарешті, для перевірки статусу візьму AWS Lambda - тут достатньо безплатних хвилин виконання. Лямбда-функція повинна запускатись раз на годину, дивитись таймстемп файлу на S3, та, якщо він перебільшує годину чи дві, повідомляти в Slack.
Slack, на відміну від GitHub, не має зручного механізму відправляти повідомлення зі скрипту — тож доведеться створити аплікацію, налаштувати, отримати адресу для вебхуків, і потім вже відправляти повідомлення туди.
-
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)). Тобто, готуємо записи без зберігання, потім беремо від них атрибути й вставляємо однією командою.Такий метод не створюватиме асоціацій, тому їх доведеться створювати окремою командою.
-
Перші враження від PagerDuty
🚨⚠️⏰ Перші враження від PagerDuty: це не магічне рішення всім проблемам моніторингу та підтримки.
У нас моніторинг трохи більш тривожний, ніж потрібно. В ідеалі а) інциденти трапляються рідко та б) кожний дійсно вимагає уваги. Тобто якщо о четвертій годині ранку тобі дзвонить PagerDuty, це має значити тільки одне — треба продерти очі та бігти виправляти. Якщо ж порушене одне з цих правил, то інциденти втрачають нашу увагу, а без уваги PagerDuty - марна трата грошей.
Це автоматично значить, що PagerDuty не місце на стейджингу, хоча це здавалось хорошою ідеєю, бо стейджинги теж треба підтримувати живими.
Також, пряма інтеграція тривог AWS CloudWatch з PagerDuty погано спрацювала, бо тривог в нас багато, і не всі вони потребують термінового розвʼязання. Тут більше недолік CloudWatch - їх тривоги суто чорно-білі, немає ані “рівня попередження”, ані “не дуже важливих” тривог.
Коротше, PagerDuty ще треба налаштувати на ситуації “кинути всі справи та виправляти”, а за CloudWatch доведеться й далі спостерігати, але іншими способами.
-
Як ефективно програмувати, коли немає звʼязку?
🌑🔦👩💻 Як ефективно програмувати, коли немає звʼязку? Головна проблема цих днів — відсутність швидкісного інтернету. Ноутбука вистачає на багато годин. Але ж звʼязок при відсутності електрики швидко псується. Дротовий інтернет не працює без роутерів, мобільні мережі перенавантажуються, бо всі разом перестрибують на них.
Головний інструмент програміста — редактор — не потребує інтернету. Тут нам вже пощастило, порівняно з маркетологами або аналітиками. Тож код можна набирати, доки ноутбук не розрядиться.
Далі, програми потрібно запускати. Звісно, типові проєкти цілком готові до локального запуску. Якщо ні, то саме час зайнятись цим технічним боргом, як зʼявиться вихід в інтернет.
Але деякі проєкти потребують інтеграції з тим чи іншим вебсервісом. Для багатьох сервісів є емуляція, наприклад, localstack для AWS, або набір емуляторів Firebase.
Хоча я розумію, що інколи емуляція не підходить. Тоді можна знайти альтернативну роботу — наприклад, написання тестів для коду, що вже існує (бо тести ж мають працювати без зовнішніх залежностей?). Або виправлення правил лінтера. Для Terraform є такі вичерпні лінтери на кшталт tfsec, що я впевнений, що ваша конфігурація їх ще не проходить. :)
Додатковий фактор — документація. Тут тяжко без інтернету, знаю. Базову документацію зручно тримати локально — я вже багато років користують Dash. Туди, до речі, можна завантажити й документацію до окремих пакетів. І навіть топові запитання StackOverflow, хоча це мені мало допомагало.
Також треба згадати, що на більшості сучасних мов ті пакети, що є залежностями, вже є завантаженими локально, і читати їх код можна без GitHub. В Ruby є зручна команда
bundle open, але знайти місце розташування залежностей завжди можна вручну.Ці навички також допоможуть нам також зручно працювати в подорожах, або й просто економити час — локальні ресурси завжди є і будуть швидше віддалених.
-
Метод фітнес-трекера в продуктивності, щому це працює для мене
🚶♂️📆🐝 Продовжуючи тему з плануванням, якщо я вже її зачепив. Як я вже казав, системи в мене не дуже працюють. Розкажу, що працює.
Найбільш безперервне явище в моєму житті, вже 9 років — то виходжування норми кроків на фітнес-трекері (або тепер — калорій). Пропускаю я не більше як день щопівроку. Це само по собі дуже важливе, хоч і базове досягнення. Але воно наштовхнуло мене на цілу теорію кермування життям. Чому фітнес-трекер так добре працює?
-
Очікування трекера регулярні, а саме — щоденні. Тобто кожного дня — новий успіх — та відчуття виконаної справи. Але й новий початок. Це рятує від часової преференції.
-
Очікування мають чітку мету, прогрес до якої можна легко оцінити. Легко зрозуміти, чи гарно просувається день, або скільки залишилось доробити.
-
Це зовнішня система, яка працює, навіть якщо про неї не думати. Багато систем розсипаються саме тому, що їх треба підтримувати самотужки, і чим більше ризик недотримання системи, тим більше й ризик її неіснування.
Останнім часом я багато обмірковую, як цю “теорію фітнес-трекера” застосувати до інших галузей життя.
Є ну дуже крутий сервіс Beeminder. Він забирає в тебе гроші, коли ти не дотримуєшся власно виставленого стандарту. Раджу спробувати, бо це дуже особливе відчуття.
-
-
Мій досвід тайм-менеджменту. GTD та інше.
В мене складні відносини з плануванням. З одного боку, методологія Getting Things Done перегорнула мені життя, і я досі вважаю її ґрунтовною для впорядковування власного життя. З іншого боку, це було років 15 тому, і за весь цей час GTD в мене так і не прижилась.
Трагікомічно знаходити списки задач за пʼять років тому, з яких більша частина так і не відбулась. За той самий час, звісно, було виконано безліч ніде не записаних справ. Чому тоді мене це турбує? Тому, що мені досі не зрозуміло, як скерувати життя в напрямку своїх цілей, або принаймні зрозуміти, що ті цілі наближаються.
Можливо, що буддизм має правильну відповідь. А саме: хапатись і намагатись керувати життям — то є дукха; натомість треба пливти за течією. Власне, останні роки я нічого не планую детально, а просто намагаюсь робити крок за кроком до мети. Таке собі “планування методом A*”. Це не завдяки буддизму, а через втрату довіри до систем організації.
Але цілей та обовʼязків у житті багато, і хіба за всіма встежиш? Хочеться хоча б хапатись за свої обіцянки, щоб не забути їх виконати. Тож пошук системи - або ж більше роздуми над нею - тривають.
-
Як поставити зірку в 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.