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

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

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

24.04.2025

Швидкі задачі

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

Так, є архетипова ситуація, де розробник каже на задачу - “ой, справ на пʼять хвилин” - а вона обертається цілим днем. Це не скасовує того, що, є й такі задачі, які дійсно можна зробити, покрити тестами, та оформити за лічені хвилини. Особливо коли це стосується прибирання (тобто видалення) коду, або дрібних змін в інтерфейсі.

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

Але як тільки така робота стає поза поточним контекстом, планувати її стає важко. Керування проєктами гарно працює з епіками на тижні та місяці роботи, а не на хвилини. Мені стає боляче слухати про “заплануймо це на після оцього”, коли йдеться про годину чи дві роботи.

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


23.04.2025

ZIP проти .tar.gz

🗜️ На мою думку, необхідно знати рівно два архівних формати (“формати” насправді умовно, про що нижче.) Різниця між ними дуже суттєва.

Справа тут в чому. Алгоритми стискання всі працюють на потоках даних. Про файли та каталоги вони нічого не знають. Тому коли ми хочемо стиснути каталог, доведеться спочатку перетворити його на потік даних.

.tar.gz - це насправді комбінація двох архівів (за принципом Unix “кожна програма робить щось одне”.) tar зберігає каталог файлів у вигляді потоку. Щоб прочитати один з файлів, доведеться бігти по архіву, поки його не знайдеш. gz стискає один файл — це не обовʼязково файл .tar, може бути будь-який, наприклад, .json.gz - якщо вам потрібно стиснути лише один файл, tar не потрібний.

ZIP зберігає файли каталогом, де кожний файл стиснутий окремо. Тобто на верхньому рівні ZIP файлу сидить каталог, в ньому можна знайти будь-який файл та розпакувати. На ZIP побудовано багато форматів файлів — це JAR, DOCX, ODT тощо. На відміну від .tar.gz, ZIP-архів можна швидко передивлятися, розпаковувати окремі файли, та навіть редагувати архів — бо в .tar.gz можна тільки створити його наново.

Алгоритмів стискання існує багато - gzip, bzip2, xz, Zstandard. Обирати варто тоді, коли у вас дійсно є потреба заощадити якнайбільше; в іншому разі я б брав всюдисущий gzip. До речі, ZIP теж підтримує багато алгоритмів, хоча “нормальний” такий саме, як і в gzip - DEFLATE.

А ще окрім стискання є шифрування. Тут ZIP програє, бо в нього досі немає шифрування аж всього змісту архіву. А з .tar.gz все просто — зверху накидається шифрування, та виходить .tar.gz.enc чи .tar.gz.pgp.

Виходить, вся різниця в тому, що .tar.gz суттєво простіше, зате у .zip можна швидко передивлятися зміст архіву та редагувати його. Але головне, на мою думку, дотримуватися цих двох поширених форматів та не лізти в екзотику.


22.04.2025

Oblivion

Сьогодні абсолютно несподівано вийшла оновлена версія Oblivion: Remastered. Звісно, я поки нічого, окрім вступу, в ній не бачив, але поки виглядає як дуже цікавий ремастер, де наче оновлений графічний рушій з Unreal Engine сидить на старому ядрі. Не виключаю, що вони перевіряють такий підхід для використання в нових іграх, а не тільки для ремастера. В ремастері є стара знайома тека Data, наповнена старими знайомими файлами Oblivion, тож я гадаю, можливо й моди будуть працювати.

Але хотілося натомість згадати, як вийшов оригінал Oblivion. Ще до того ми з друзями були фанатами Morrowind та чекали виходу наступника. Обіцяли, що це буде “гра для компʼютерів майбутнього” та буде надзвичайно крутіша за Morrowind. В ту епоху (2004) інтернет був дуже обмежено, тому більшість інформації розходилася плітками. Чесно, набагато цікавіше уявляти, яка вона буде та гра з описів, ніж бачити трейлер. Хоча зрештою всі ті фантазії виявлялися хибними.

Хоча що було чистою правдою — на моєму компʼютері (здається, із Radeon 9250) Oblivion ледве йшов. Запускався — що вже успіх — але гальмував так, що доводилося знижувати якість та дальність зору до мінімуму — що не допомагало. Згодом знайшов програму, здається, Oldbivion, яка підставляла спрощені шейдери. Уявляєте, спрощені шейдери, щоб гра йшла! Перший та останній раз довелося таке робити.

В мене мішані відчуття від Oblivion. В ньому багато цікавих квестів та мальовничих локацій. Та я бозна скільки програв в нього юнаком. Але з тим в Oblivion жахлива прогресія та бойовка, яка з часом стає тільки нудніше. Тому не сумую за ним. Для мене, Morrowind досі є верхівкою формули Elder Scrolls. Та судячи з активної сцени модів для неї, не тільки для мене.


21.04.2025

Резервне копіювання для Ping

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

На жаль, забув випустити раніше. Але ось що допомогло. Моя власна копія почала зависати на запуску. В XCode дуже легко зрозуміти. що зависає — достатньо поставити застосунок на паузу. Тому коли дістався до XCode, то відразу побачив, що висне — не сама резервна копія — а її завантаження до iCloud, метод setUbiquitous.

Як мені здається, проблема була в тому, що моя альфа-версія робила копію на кожний запуск, та їх накопичилося дві з гаком тисячі в одній директорії в iCloud. Як мені здається, така кількість файлів уповільнює роботу iCloud. Бо більше нічого не змінювалося, а сам файл розміром лише 300 Кб.

Так що довелося закінчити фічу — робити копіювання раз на день, додати вимикач та допомогу. Завдяки використанню @globalActor виніс роботу з головного потоку. Тут у Swift цікаво: async/await роблять код рівночасним, але залишають виконання в головному потоці (тобто гальмують інтерфейс застосунку.) Щоб зробити код ще й паралельним, потрібно винести його в актора.

Також зазначу. що бета-версії застосунків в Apple TestFlight згоряють за 90 днів. Тобто кожні 90 днів потрібно викладати нову версію, щоб бета-користувачі не втратили доступ. Та в мене сьогодні минуло 79! Радий, що через цю ситуацію встиг згадати та скоригувати курс.


20.04.2025

Кава та сон

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

І тут теж було несподівано, бо я не став спати краще. Скоріше навіть гірше, бо все літо прокидався дуже рано та не міг заснути. Чи то ластівки заважали, чи кішка, чи сонце у вікно — в будь-якому разі був постійно не виспаний.

А після повернення до кави — не став спати гірше. Навіть коли випʼю кави о восьмій вечора. Так що, емпірично для себе, зробив висновок, що кава — це принаймні не головне.

Навпаки, що дійсно впливає на сон: спорт. Точно сплю міцніше, якщо до того розганяю пульс до кардіо зони. Також алкоголь помітно погано впливає.

Ще, нарешті, про неспокійну голову перед сном. Дедалі не легше зберігати спокій в умовах війни та невизначеності — я вже мовчу про завищені очікування від себе. Мені допомагає дивитися на минулий день не в абсолютних величинах, а відносно до себе. Чи я, зважаючи на обставини та можливості, зробив достатньо? Чи я зміг діяти правильно? Чи можна, якщо хочете, назвати це “правильною поведінкою”?

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


19.04.2025

Протоколи розумного будинку: Matter

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

По-перше, Matter містить протокол прикладного шару. Того, на якому всі питання комунікації вже вирішені, та можна зайнятися передачею змісту. Як HTTP, SMTP чи SSH. Також, Matter стандартизує всі кроки звʼязку пристроїв IoT - від виявлення та підключення до навіть конкретних типів пристроїв та їхніх команд.

Таким чином, Matter націлений на як не найголовнішу проблему розумного будинку — розрізненість. Бо без стандарту в кожного виробника була (є!) власна екосистема. Але справжні проблеми почалися із появою голосових помічників (або, іншими словами, втручанням мегакорпорацій в саме серце оселі.) Бо кожний виробник ще й мусив розробити інтеграції для кожного помічника.

(Це та галузь, де відкрите ПЗ - HomeAssistant тощо — на зусиллях ентузіастів досягло більше, ніж мегакорпорації. Втім, це покладається на технічну грамотність користувачів, та складно уявити собі HA в кожному будинку.)

Отже, (ті самі мегакорпорації зібралися та) придумали стандарт Matter, з яким будь-який сумісний пристрій можна підʼєднати до будь-якого центру керування. А також до декількох (Multi-Admin). А також навіть поєднувати пристрої між собою — наприклад, зʼєднати вимикач з лампою в самодостатню пару.

В Matter багато плюсів. Він побудований на відкритих технологіях: мережі IP (в тому числі й Thread), сертифікати PKI, виявлення mDNS. Він повністю локальний, на відміну від 99% екосистем виробників. Він звільняє виробників від розробки власної хмари та застосунку та дозволяє сфокусуватися на якісних пристроях. Через це відкриває шлях для маленьких виробників.

Мінус, очевидний — стандарт нічого не значить, поки його не підтримують. Причому якісно, а не аби як. Також, Matter містить обмежений набір категорій та функцій (який розширяється). Та він фактично потребує підтримки Thread (або Wi-Fi чи Ethernet.) Але наразі головний недолік — це дуже обмежений вибір пристроїв.


18.04.2025

Глибше в кролячу нору mDNS

Пробачте, але в mDNS/DNS-SD стільки моментів, які мене змусили зупинитися та подумати, що треба про це розповісти.

По-перше, що таке multicast? Я знав про зʼєднання 1-до-1 та про broadcast - поширення сигналу на всі вузли. А Multicast - це буквально модель publish/subscribe для мережі IP. Для цього виділена категорія адрес (224.0.0.x) та повідомлення на ці адреси приймаються всіма слухачами в мережі. Звісно, це працює тільки для протоколів без сесії, тобто UDP, QUIC тощо, але не TCP.

Є реєстр відомих адрес Multicast, так само як і стандартних призначень портів. Як я розумію, Multicast більше використовується для початкового налаштування та виявлення, ніж для постійного поширення повідомлень.

Як це працює з Ethernet, зрозуміло (пакети розсилаються всім інтерфейсам, та фільтруються з боку отримувача). Але як Multicast можливий за Wi-Fi? Виявляється, так, є особливий режим надсилання за Wi-Fi, коли пакет призначається не одному, а всім клієнтам, та для того у мережі навіть є груповий ключ. Ось більше інформації та ще тут.

Чи можна DNS-SD використати у власних проєктах? Авжеж! Наприклад, для пошуку партнерів для гри в локальній мережі. Або синхронізації застосунку з телефону із компʼютером (забуте мистецтво.) Для того доведеться визначити системний сервіс DNS-SD та інтегруватися з ним. В macOS це mDNSResponder (скількі раз я його помічав, але не розумів, що він робить!), а оголосити сервіс можна тією ж утилітою dns-sd. Тобто все ж “центральний” реєстр сервісів є, але на рівні кожної машини.


17.04.2025

Протоколи розумного будинку: mDNS, DNS-SD, DNS-SRP

А ви замислювались колись, як взагалі пристрої знаходять один одного в мережі? Хто подумав DNS, той вгадав. Але є нюанси.

По-перше, як взагалі працює DNS? Це протокол на основі UDP, тобто асинхронний, тобто дуже спрощено, ви гукаєте у простір “підкажіть адресу вузла (або іншу інформацію)”, та звідкілясь приходить відповідь. В типовому сценарії ви питаєте в конкретного вузла, але насправді відповідь часто приходить не звідти.

Але із виявленням пристроїв все ще цікавіше. Бо тут запит DNS йде на всі адреси в мережі — що називається mDNS, multicast DNS. Та відповідає на нього не роутер чи інший центральний вузол, а самі пристрої! Це називається DNS-SD - стандарт DNS для виявлення сервісів. В macOS є вбудована утиліта для нього, на Linux/Windows наче теж є аналоги. Ось, будь ласка, це команда “агов, хто в цій мережі взагалі підтримує DNS-SD?”

dns-sd -B _services._dns-sd._udp

(Взагалі звичайний dig теж вміє робити запити до mDNS, коли не поламаний):

dig @224.0.0.251 -p 5353 -t ptr _services._dns-sd._udp.local

Я аж рот роззявив від кількості та від різноманіття сервісів. Наприклад, тут є й _airplay, й _home-assistant, а не тільки розумні пристрої.

Як можна здогадатися, така інформація не тільки корисна, а й небезпечна, оскільки запит може надіслати будь-яка програма чи пристрій в мережі. Нарешті зрозумів, чому свіжі версії macOS видають попередження на кшталт “Дозволити застосунку бачити пристрої в локальній мережі.” Бо навіть не потрібно нічого сканувати, як Трініті в Матриці — пристрої самі все скажуть.

Для пристроїв з батарейкою такий спосіб, звісно, не підходить. Тому є інший протокол - DNS-SRP - для того, щоб реєструвати вузли на центральному сервері. Причому він цілком сумісний з DNS-SD, оскільки останньому не важливо, який саме вузол надсилає відповідь — сам за себе чи через посередника.


16.04.2025

Протоколи розумного будинку: Thread

Спочатку цікавий факт: більшість технологій розумного будинку використовують один та той самий радіопротокол IEEE 802.15.4. (Може, хто помічав, що Wi-Fi - це “сусідній” IEEE 802.11.) Це протокол фізичного рівня, тобто відповідає за те, як дані кодуються у радіосигнали. Тому що Zigbee, що Thread, що ще декілька протоколів — це все IEEEE 802.15.4 на частоті 2.4 ГГц (Так само як і “старий” Wi-Fi та мікрохвильовки.)

🧶 Thread - так само як і Zigbee, протокол сітчастий, тобто вузли передають посилання між собою та утворюють надійну “сітку” комунікацій. Так само тут вузли з батарейками працюють економно, а вузли з дротом виступають ретрансляторами. Так само, чим більше у вас пристроїв з Thread - тим надійніше ваша домашня мережа. Звісно, це буде мережа, окрема від Zigbee, хоча багато пристроїв підтримують обидва протоколи.

Навіщо ж тоді ще один протокол? Головна особливість Thread - що вузли мають адреси IPv6. (Їх є 340 ундецильйонів — вистачить на всіх.) Це значить, що замість ізольованої мережі, Thread стає частиною локальної та глобальної мережі IP. (Головним транспортним протоколом тут є асинхронний UDP, тому, можна сказати, UDP/IP.)

Звісно ж, це суттєво спрощує архітектуру. З Zigbee чи BLE потрібний привілейований посередник, що перекладає повідомлення між застосунками в TCP/IP та пристроями в Zigbee/BLE. Причому звісно ж прямого шляху це зробити немає — потрібний принаймні якийсь API. А в Thread координатор мережі є простим шлюзом, що займається тільки маршрутизацією. Йому, наприклад, не потрібно знати зміст повідомлень, або розуміти призначення пристроїв. По-перше, так безпечніше, по-друге, шлюзи Thread мають кращу сумісність між виробниками.

З усім тим, Thread стандарт відносно новий (2014 року) та пристроїв з ним значно менше, ніж із Zigbee. На щастя, принаймні вони можуть ділити один радіомодуль, тож можна очікувати більше пристроїв з подвійним стандартом. Субʼєктивно це кращий протокол, але чи він переможе — покаже час.

(Бачите, це не зовсім так, що “було 10 стандартів, додали ще один”. Еволюція простежується.)


15.04.2025

AWS та GCP: не такі вони вже й схожі

Я вже років 8 працюю з AWS, а от з Google Cloud Platform довелося стикнутися навсправжки тільки цього року. До того було хіба що Firebase та щось дрібненьке. Втім, в мене було переконання, що хмарна платформа — вона й в Гуглі хмарна платформа, та різниця хіба що в брендінгу та в назвах. (Ну, до речі, в хостингу для VPS дійсно майже так і є, тому було з чого так думати.)

Зате коли довелося налаштовувати авторизацію з AWS в GCP, вмочив ноги в гуглівську модель авторизації. А там… все зовсім не так, як я звик. В AWS доступ до ресурсів оголошується документом-політикою, де перелічені ресурси та дозволені операції з ними. Ну може декількома політиками. Але я легко можу побачити, до чого є доступи в конкретного користувача чи ролі.

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

Тепер, нещодавно також довелося налаштувати на GCP проксі. Та знову, я звик, що в AWS є Балансувальник, а в нього є Слухачі, які направляють запити до Групи Цілей. А на GCP є Глобальна Адреса, Проксі, Відображення URL, та Бекенд-Сервіс. Я тут теж не знаюся, тому реально довго шукав, які взагалі ресурси мені потрібні та як вони називаються. Зокрема те, що в UI є Load Balancers, а в Terraform просто нічого схожого немає. Виявляється, що ото ці Load Balancers збираються з цілої купи абстракцій.

Так що не варто поспішати зі спрощеннями, поки досвіду немає. Зате, раніше я думав, що AWS надто заплутаний, а тепер здається, навпаки по-людськи зроблено.