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

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

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

13.12.2022

Опубліковав покращену стрічку для Hacker News

👨‍💻📢🥳 Сьогодні опублікував покращену стрічку для Hacker News, про яку писав у листопаді. Сама стрічка не змінилась — я їй користуюсь вже декілька тижнів і дуже задоволений. Довелося тільки перетворити її на продукт:


12.12.2022

Висновки від розгортування величезної переробки для нашого Redshift

🗄️🛫🌧️ Побачила світло продакшна велике перероблення схеми Redshift, яка тривала понад два місяці. Кілька думок:


11.12.2022

Чому варто частіше писати в підтримку

Сьогоденний пост про підтримку. А саме, про те, що не треба соромитися туди писати.

Мені доводиться чергувати на другій лінії підтримки. Якщо це чомусь мене навчило, то це тому, що деколи клієнти роблять набагато більш дивні запити, ніж те, з чим подумав би звернутися я сам.

Ну, наприклад: дехто зареєструвався і раптово витратив весь місячний обсяг за один день. Пише “скиньте, будь ласка, лічильник, бо я помилився та зробив надто великий тест.” Я б в такому випадку чекав би кінця місяця, бо сам винний.

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

Про гроші окремий момент. Бюджети бізнесу на порядки вище, ніж витрати користувачів. Тому якщо ти, скажімо, помилково оформив більшу підписку, ніж хотів, то повернути гроші — не така значна витрата для бізнесу, як була для тебе. Зазвичай, на моєму досвіді, все повертають, якщо запитати.

А що порадує підтримку, то це гарно поставлений та деталізований запит, наприклад, так, як радить ставити питання StackOverflow.


10.12.2022

Огляд сервісу Healthchecks.io

Мій проєкт вихідного дня скасувався, тому що читач Руслан звернув увагу на Healthchecks.io. Цей сервіс робить все, що мені потрібно, та є розвиненим та зрілим — рекомендуватиму його своїй команді. Мені тут немає чого додати.

Окрім моніторингу роутера, такий сервіс здатний до інших задач. Можна наглядати за системами, які через міри безпеки (або задля простоти) не мають доступу ззовні — наприклад, сервер фонових задач. І ще одна важлива проблема, для якої в мене досі не було розвʼязку: припустимо, є скрипт, що має працювати періодично (ну може, щоб оновити RSS стрічку). Як дізнатись, що скрипт дійсно працює? А точніше, як помітити, що скрипт припинив працювати? Тепер для цього достатньо додати до кінця скрипту виклик Healthchecks.io.

Потім зʼясував, як працює інтеграція IFTTT з вебхуками. Для цього у них є сервіс Maker. Цей сервіс дає тобі ключ, з яким можна відправляти події на спеціальну адресу https://maker.ifttt.com/trigger/{код події}/json/with/key/{ключ}. Потім за кодом події можна підʼєднати до різних вебхуків різні реакції. Так що мій прототип для Slack успішно переїхав на Healthchecks.io + IFTTT.


09.12.2022

Плани проєкту "зворотній ping" - виділення МVP

📐⚖️🚧 Окреслюю MVP для проєкту “чи є роутер онлайн”, який хочу зробити за вихідні. Та треба памʼятати, що розробка — це тільки половина діла (буквально!), а іншу половину ти маєш витратити на базову інформаційну сторінку та розкрутку.

Обрав такий підхід до планування MVP: виділити головну функцію в проєкті, та зробити рівно стільки, скільки потрібно, щоб її уможливити. Чесно кажучи, тільки тому за це берусь, що така головна функція вже відома, та навіть прототип вже готовий — за цей тиждень чимало разів довелося його випробувати.

Що ж входить у мій MVP?

Такий MVP має замінити мій прототип з Firebase: замість прямого надсилання у Slack використаю IFTTT.


08.12.2022

Плани проєкту "зворотній ping" - вибір фронтенду

💬🪟🧑‍🎨 Наступне питання — на чому робити фронтенд? Та, хоча я великий фанат React, але для маленького проєкту, напевно, краще взяти Svelte.

Я вже робив маленький проєкт на Svelte - власне, коментарі на моєму блозі. Порівняно з React, вона чудово вирішує базові потреби додатка і дає можливість швидко розпочати розв’язання задач бізнесу.

Якщо не бачили, то у Svelte свій, особливий синтаксис: кожний файл містить один компонент; у файлі спочатку йде код JavaScript (майже) - імпорти та логіка, а потім шаблон HTML (майже). В результаті отримуємо більш-менш те ж саме, що й у React. Але, якщо React використовує стандартний JavaScript (та дуже прямолінійний JSX, то Svelte додає до JavaScript купу зручностей та синтаксичного цукру. Розібратися в цьому синтаксису навряд чи вийде без підручника. Це найбільший ризик у виборі Svelte, і саме через синтаксис я не думаю, що було б зручно писати на Svelte великий проєкт.

Також, порівняно з React, Svelte пропонує більш завершений комплект — він включає і сховище (аналог Redux), і пакувальник (аналог Webpack). TypeScript повністю підтримується — для мене це є необхідність. Тож, без зайвих налаштувань, можна відразу робити щось корисне. Це теж життєво необхідно для маленького сайд-проєкту.

Мабуть, доцільно будет порявняти Svelte з Ruby on Rails, де теж на кожну потребу є свій особливий і зручний DSL.


07.12.2022

Плани проєкту "зворотній ping" - вибір мови та хостінгу

📋🦡🎈 Продовжую планування для проєкту “пінг, але навпаки”.

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

При меті досягти найбільше з найменшими витратами мій вибір буде Golang та fly.io. Тут почати можна вже за $2 на місяць, і не хвилюватись про кількість запитів.

Але є інша сторона витрат — база даних. Зазвичай база — то окремий сервіс, тобто ще $2 на місяць, а скоріше за все, більше, бо сучасні бази не хочуть працювати на 256 MB оперативної памʼяті. Тому вирішив зробити ще один неординарний хід та розмістити базу даних всередині головного додатка, тобто вбудувати. Тоді не тільки не потрібно переплачувати, а ще й працюватиме швидше.

Можна було взяти для цього SQLite3, але ще краще, на мій погляд, випробувати одну з декількох вбудованих key-value баз, що існують для Golang. Поки зупинився на базі Badger. Якщо спрощувати, то це типу Redis, але працюватиме прямо в додатку. Вміє вона зберігати дані на диск (бо як без цього), синхронізувати (в майбутньому) декілька вузлів, підтримує транзакції. Єдине, що мені трохи не подобається, це те, що API роботи з базою — це не “просто писати в структуру даних”, а все ж таки схоже на роботу з сервісом.


06.12.2022

Плани проєкту "зворотній ping" за допомогою IFTTT

💡➡️📥 Якщо розвивати ідею про перевірку, чи є звʼязок, то можна зробити цікавий проєкт — такий собі зворотній ping. Ідея така: замість того, щоб пінгувати сервіс, сервіс отримує URL, який він має регулярно викликати. Корисно це тоді, коли сервіс не є досяжний напряму.

З іншого боку, повідомляти о наявності в Slack - це добре, але недостатньо; гарно було б додавати запис у календар. Або, я б хотів сам отримувати повідомлення про те, що звʼязок зʼявився, поки я не вдома.

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

Для цього достатньо розробити API, що відповідатиме специфікації. Тож розбирався, як воно робиться.

Головне - IFTTT опитуватиме мій сервіс щогодини. Сервіс має повернути останню подію, або декілька подій. З одного боку, це легко підтримувати, бо навантаження не таке велике. З іншого, година — може й занадто довга затримка. Якщо потрібно відправити подію скоріше, то є ще “API реального часу”, тобто просто URL, за яким можна попросити IFTTT опитати сервіс скоріше.

Також потрібно зробити аутентифікацію та OAuth сервер. Та якийсь мінімальний інтерфейс налаштувань. Та купу маркетингових матеріалів. Але має вийти цікавий маленький проєкт, нічого схожого я поки не знайшов.


05.12.2022

Мої рекомендації протоколу для 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 раджу брати, тільки якщо потрібна величезна пропускна здатність. І тільки обмежено. Бо цим ви завжди втрачатимете простоту.


04.12.2022

Як запостити файл на 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.

Якось так. Повний скрипт тут. Радий, що такі задачі зустрічаються хіба що заради вправи або забави.