Стендап Сьогодні
Що я зробив, що я хочу зробити, і що це все значить.
Повсякденні здобутки в форматі стендапу.
Детальніше в статті
Підписатись на RSS
📢
Канал в Telegram @stendap_sogodni
🦣
@stendap_sogodni@shevtsov.me в Федиверсі
03.02.2023
Поради як тримати Terraform в простоті
Terraform, хоч і є декларативною мовою програмування, але все ж таки вміє робити чимало функціональних перетворень над даними. Деякі дуже корисні - formatlist допоможе переформатувати рядки за шаблоном, та я часто їй користуюсь — наприклад, щоб перетворити IP на маски мережі командою formatlist("%s/32", local.ips). Повноцінного програмування все одно не вийде, але можна написати досить складні перетворення. (Варто памʼятати, що замість звичної функції map списки відображаються командою for. )
Так я колись витратив пару днів, щоб генерувати правильну розбивку IP адрес за мережами та машинами. По-перше, це зайняло купу часу. По-друге — як тільки зʼявилися додаткові вимоги, адаптувати код не вийшло. Тому що, по-третє — хоча я намагався наповнити код коментарями, все одно було забув, як воно працює, а головне — чому. Як ілюстрацію пропоную подивитись функцію matchkeys - таку езотерику я в повноцінних мовах не бачив.
Тому моя поточна думка — що краще було б вручну задати на прості вихідні дані, а розгорнутий кінцевий результат перетворень. Так, доведеться більше робити вручну. Але головне, що ця конфігурація буде більше схожа на топологію самих ресурсів, а значить, буде легше зʼясувати, що до чого. Що, на мою думку, краще, ніж коли конфігурація проста, але як з неї створюються ресурси — абсолютно незрозуміло. До того ж конфігурацію можна генерувати не вручну, а скриптом, та передавати у форматі JSON.
А ще, в усіх можливих випадках, раджу адресувати повторювані ресурси ключами, а не індексами. Тобто замість метааргументу count вживати for_each.
02.02.2023
Пост симпатій до бази даних Redis
Пост симпатій до бази даних Redis. Всі знають, як використати Redis у якості кеша. Колись давно цю задачу виконував memcached (який ще досі живий!), але зараз всюди, де я знаю, роль кешу зайняв Redis. Та, без заперечення, цю роль він грає чудово. Але Redis вміє набагато більше. Оскільки Redis тримає всі дані в оперативній памʼяті, правильно буде думати про нього не як базу даних, а як зовнішню оперативну памʼять вашого додатка.
Тому Redis ідеально підходить для даних, потрібних в реальному часі. Лічильники, передача повідомлень, таке інше. Порівняно з внутрішньою памʼяттю, Redis буде доступним з різних машин та збереже дані навіть при перезапуску додатка, а також і при перезапуску сервера Redis теж — хоча гарантії надійності тут слабкі, тож для довготривалого збереження краще обрати справжню базу даних.
Насправді у Redis є сила-силенна команд, які уможливлюють складніші обчислення саме на сервері. Наприклад, мені колись довелось використати команди для роботи над бітовими рядками. Цінним є те, що у кожної команди зазначена її обчислювальна складність, тобто можна напевно розрахувати швидкодію майбутнього рішення. Тож, якщо у вас є додаток, скажімо, на Ruby, та потрібно прискорити якийсь алгоритм, то можливо, Redis та його розширені команди — це все, що потрібно. А далі можна навіть перенести алгоритм прямо у Redis, бо він підтримує скрипти на Lua… По цьому шляху я теж пройшов, але нарешті вирішив переписати все на Go - проте прототип вийшов чудовий.
01.02.2023
Як переконатись, що архітектура витримає? Йти від зворотного.
Продовжуючи тему про стрес-тести — як все ж таки переконатись, що архітектура витримає навантаження, якого у вас зараз немає навіть близько? Я пропоную виходити зі зворотного. Чого ваша архітектура не витримає? На мою думку, це питання менш абстрактне, та тому з ним легше впоратись — та навіть перевірити.
Багато де межі дійсно немає — наприклад, при можливості лінійного масштабування, це просто питання грошей. Тут епоха хмарної архітектури відкрила для нас суцільно нові проєкти, бо до появи AWS та іншого масштабування закінчувалось на одній або декількох машинах, а далі — вже зовсім інші витрати. Також є глобальні хмарні сервіси, такі як AWS Kinesis Firehose, які мають абсолютно космічні межі використання, тому на них можна впевнено покластися (теж за гроші, звісно.)
Інколи рішення працює для будь-яких обсягів, але впирається в фізичну межу. Так, база даних зі зберіганням у памʼяті (Redis) чудово працюватиме, поки влазить в памʼять однієї машини. Проте памʼять машини — це вже не 640Kb з відомої цитати Біла Ґейтса, а, у випадку AWS ElastiCache, до 640 ГІГАбайт. Тож влізти може багато.
Та, нарешті, є багато підходів, які масштабуватись не будуть, а працюють зараз тільки через низький обсяг клієнтів (або ж взагалі до появи справжніх клієнтів.) Наприклад, якщо ми свідомо знаємо, що складність обробки зростає як квадрат кількості користувачів. Так, з 10 тестовими користувачами все працює добре — але ж на 10 тисяч ми ніяк не вийдемо. Сучасні програмісти рідко пишуть щось складне, але ось накоїти проблем в базі даних — це ми можемо.
Коротше, чесному інженеру на відкрите питання “чи все буде добре” відповідати складно. Краще перетворити його на “що піде паскудно”.
31.01.2023
Перший місяць користування блокнотом для самоменеджменту
Вже цілий місяць я веду свої справи по блокноту. Не кинув поки! Що стало несподіваною перевагою — блокнот дуже добре ізолює увагу. Порівняно з телефоном або ноутбуком, коли працюєш з блокнотом, то немає на що відвернутися. Бо, мабуть, у всіх бувало так, що взяв в телефон у руки — а через пʼять хвилин вже згадуєш, для чого. Тому щоранку я роблю каву та сідаю за блокнот писати справи на день, а потім вже лізу в інтернет. А якщо все добре, то щовечора перед сном також записую все, що крутиться в голові. Така собі медитація на блокнот виходить.
Як на мене, то у самоорганізації є етапи. На початку в голові є декілька гострих, важливих задач, заради яких зазвичай і починають щось записувати. Коли з гострими задачами закінчено, раптом виявляється, що в тебе купа ідей, які припинили бути репресованими теми гострими, і також хочуть бути записаними та зробленими. На цьому етапі в мене ідеї просто фонтанують десятками. Далі, третій етап — все, що записано, вже неможливо зробити ані сьогодні, ані завтра; тут зʼявляється список проєктів та набирає чинності якесь розставляння пріоритетів. (Я зараз тут.) А після того, як здобуваєш певну кількість результатів, стає питання вищого порядку: навіщо все це, і куди я рухаюсь? Тут вже треба розбиратись з довгостроковими цілями, а також зонами відповідальності. На цьому моє розуміння поки закінчується.
30.01.2023
Порада про захист сайтів з Cloudflare, та інша порада про цінність вузько націленого коду.
-
Якщо використовуєте Cloudflare, моя порада — встановити у правилах сторінок високий рівень безпеки для вашої сторінки логіну (а також, можливо, реєстрації та білінгу, залежить.) Це у
Page rules -> додати -> Security Level: High. До такого висновку я прийшов після того, як припинив чергову атаку по підбору паролів на нашому сайті. А ще цікаво, що наш нападник, який мав доступ до тисячі IP-адрес, не здогадався міняти свій User Agent, і таким чином був легко відфільтрований та знешкоджений. Добре, що Cloudflare дає всі інструменти, щоб відділити злочинні запити від нормальних, та швиденько їх заблокувати. Погано, що я поки не знайшов способу автоматично помічати такі атаки раніше. Цього разу помітив через високе споживання процесора, але це трапилось суттєво пізніше початку атаки. -
Всі інженери полюбляють узагальнені, універсальні рішення. Так приємно знати, що ти готовий до будь-чого. Але треба признати, що універсальність часто отримується в обмін на швидкодію. Іноді найкраща оптимізація — це прописати код чітко під задачу. Так в мене і трапилось: шукав шляхи оптимізації величезної SQL-вьюхи на будь-який випадок життя. А потім зрозумів, що насправді треба виписати найбільш популярні структури запитів, та зробити для них окремі, спрощені вьюхи. До речі, оскільки все це керується будівельником запитів на Ruby, то клієнти навіть не дізнаються, що від обраних аргументів міняється повністю весь запит. Так з єдиним інтерфейсом продовжуватимуть працювати як прискорені популярні запити, так і універсальні, але повільні.
29.01.2023
OpenMW: сучасний спосіб пограти у Morrowind. А також, його збірка — спосіб себе помучити.
Morrowind, на мою думку — вершина RPG-пісочниць від першого лиця. Немає у наш час більше великобюджетних ігор з левітацією (бо швидкодія), з такою кількістю діалогів (бо озвучка), та й з таким дивним, незвичним світом (бо не окупиться.) Так що, хоч грі вже понад 20 років, а спільнота досі жива та є що від неї чекати.
Сучасний спосіб грати у Morrowind - це через клієнта OpenMW; він повністю заміняє оригінальну програму, та не тільки підтримує весь функціонал, а й додає купу нового. Чого варто хоча б підтримка macOS!
Для керування модами є сучасний менеджер модів portmod. А для пошуку модів, окрім сайту NexusMods, що колись називався TES Nexus, є ще й сучасний ресурс Modding OpenMW, де зручно перелічені різні набори модів — від тих, що роблять косметичний ремонт оригінальної гри, до повних перетворень. (До речі, portmod вміє встановлювати списки модів з цього сайту.) Також наприкінці минулого року вийшли величезні доповнення карти та квестів від Tamriel Rebuilt та Skyrim: Home of the Nords.
Одним словом, для мене Morrowind залишається чудовою розвагою, яку можна запустити на ноутбуці для короткої перерви. Так воно й було, поки не захотілось більшого. Побачив, що у їхньої команди немає кому зробити збірку останньої тестової версії для M1 Mac; стабільна версія є тільки для Intel, а попередня тестова версія для M1 працює в рази краще, але вона з багами.
Що ж, я щось вмію, вирішив зробити збірку сам. Основний набутий досвід — тулчейни для веброзробників це просто космос, порівняно з тим, з чим працюють розробники на C++. Керування залежностями як таке відсутнє; залежності “просто” мають бути присутніми на твоїй машині. Щось з них може встановити Homebrew; щось потрібно стягнути та зібрати вручну. Але стандартів бібліотек як таких теж немає; буває так, що встановлена з Homebrew версія має іншу структуру та не підходить для скрипту збірки (так сталося з bullet). До речі, всі бібліотеки, які довелося збирати, використовують утиліту CMake. Кожний скрипт CMake має секцію, де він намагається вгадати, чи є на диску його залежності, та де, та в якому форматі. Інколи бібліотек є декілька, та він плутає. Інколи замість бібліотеки на M1 бере бібліотеку для Intel. Інколи він спочатку знаходить, а потім під час компіляції каже дивну помилку, причому у 100% випадків якщо щось не компілюється — то проблема з залежностями. Якщо тільки не з компілятором. Бо на різних системах все компілюється різними компіляторами, а MacOS - не сама популярна OS, та до того ж, з не дуже стабільним тулчейном.
Поки в мене вийшло зібрати додаток OpenMW, але в ньому чомусь бракує динамічних бібліотек, тому він не запускається. Спробую наступного разу, як буду сердитися на Yarn.
28.01.2023
Як працюють віджети на iOS
Вже два роки на iOS є віджети, та, напевно, всі вже звикли до цих зручних доповнень до звичайного інтерфейсу додатків. Але з боку розробки віджети стали революцією. Будь-який розробник додатків для iOS добре знає, що вся архітектура цієї операційної системи побудована на економії батареї, а значить — процесорного часу. Тільки поточний додаток отримує повний доступ до процесора; всі інші — тільки суттєво обмежений; фактично, вони стоять на паузі, якщо не отримують повідомлень та не відтворюють звук. До того ж додаток, прихований з екрана, має бути готовий, що ОС повністю завершить його роботу будь-який момент. Як же ж при такій суворій економії енергії можливо, щоб відразу декілька віджетів були постійно відображені на головному екрані?
Відповідь в тому, що віджети на iOS взагалі не є додатками. Правильніше скати, що віджет являє собою векторне зображення, тобто інструкцію про те, що треба намалювати. Технічно, є також програма, яка будує віджет, але вона викликається відносно рідко — в кращому випадку, декілька десятків разів на день. Тож віджети за своєю природою не можуть мати нічого інтерактивного, окрім кнопок-посилань. Для економії оновлень, віджет насправді задається як така собі анімація, тобто не одне, а серія зображень, які змінюються за зазначеним розкладом. Наприклад, віджет погоди може завантажити послідовність погодних станів на кожну з наступних годин по черзі. Чого він не може зробити, це щогодини ходити на сервер за новими даними. Принаймні, не гарантовано.
Така система розрахована на те, що ми можемо передбачити зміст віджета, поки додаток не змінюється. Та дійсно, за моїм досвідом, такий прогноз можливо та навіть цікаво робити. Наприклад, мій віджет для самоменеджменту враховував поточний таймбокс (наприклад, робота / дім), та показував відповідну наступну задачу. Для цього в додатку я будував серію станів для кожного таймбоксу. Така серія була актуальна, допоки ти не зайдеш у додаток — наприклад, щоб закрити задачу. Тоді віджет перемальовувався.
А ще цікаво, що структура віджета — це, фактично та буквально, SwiftUI. Як бачите, коли Apple робили декларативну бібліотеку для інтерфейсів, вони планували не просто спростити розробку та зробити її схожою на React. Вони також заклали можливість зберігати та відтворювати знімки інтерфейсу. Це корисно не тільки для віджетів, але й для Apple Watch, де економія батареї ще більш важлива.
27.01.2023
Чому важливо відмовлятись від справ
Сьогодні, нарешті, заархівував всі свої плагіни до Sublime Text. Це після того, як я вже багато років не користуюсь цим редактором, а переїхав на VS Code - де, до речі, функції моїх плагінів були вбудовані. Звісно, ніякої мотивації підтримувати плагіни не залишилось. Але припиняти проєкти — це боляче. Тому вони просто існували, накопичували жалоби користувачів на Гітхабі, та страшенно муляли мені очі.
Мало написано про те, як скасовувати справи. Література про продуктивність зазвичай турбується або про те, як закінчувати справи, або як їх розпочати. Але скасовувати найважче — принаймні, для мене — бо для цього треба признати, що ціль не буде досягнута. Легше тримати таку справу в стані зомбі. Хоча й очевидно, що багато справ не варті того, щоб їх починати, та навіть розпочавши — закінчувати. Тому, — принаймні, в мене — кожний список задач з часом загрузає в пунктах, які я вже точно (якщо бути реалістом) не зроблю. Це одна з головних причин моїх невдач з самоменеджментом. В мене завжди нових ідей більше, ніж часу на їх виконання, тому як в робочому, так і в особистому житті без свідомого видалення задач система приречена.
Зараз з блокнотом пробую такий підхід: список задач щодня переписую наново. Так застряглі задачі стають нестерпно очевидними. Під час переписування задачу можна зробити чіткіше, простіше, детальніше — а можна просто видалити. Ось ще одна можливість блокнота, яку я не можу уявити в електронній системі.
26.01.2023
Як я робив презентації у Markdown, та як їх рятувати від забуття
В мене на сайті є розділ “Доповіді”, в якому, насправді, відсутні практично всі мої доповіді. Зібрався наповнити його змістом - бо колись мені доводилось робити цілу купу презентацій. Але, поки все зупинилось: розділ був створений для презентацій, створених з бібліотекою remark.js, та його треба перероблювати на більш загальний формат сторінки, щоб влізли презентації в будь-якому форматі. Remark то така бібліотека для написання презентацій у форматі Markdown та відтворення їх у браузері. Як я бачу, підхід цей все ще популярний - в гуглі можна найти десятки схожих інструментів. Але саме Remark.js підтримується погано. І тут стає очевидною найбільша проблема таких бібліотек - презентація у нестандартному форматі вмирає з програмою, що цей формат споживає. (А стандартного Markdown для презентацій, фактично, немає.)
Але розвʼязок є - я знайшов утіліту Decktape, яка за допомогою браузера перетворює презентацію Remark.js (або ще декількох форматів) у гарний стандартний PDF - або у окремі скріншоти слайдів. У найближчому майбутньому сподіваюсь замінити Remark.js на більш звичайний розділ зі слайдами та текстом, або ж переглядачем відео або PDF. Коротше кажучи, моя порада - зберігати всі свої презентації у PDF. Якщо потрібно їх показати в браузері, то є бібліотека pdf.js.
А мій улюблений інструмент для створення презентацій на Markdown - це Deckset. Його б взяв, якщо б мене запросили робити презентацію сьогодні. На відміну від Remark.js та інших бібліотек, у Deckset є вбудований експорт в PDF.
25.01.2023
AWS DynamoDB - база для глобальних додатків
Коротенька оповідь про NoSQL базу даних AWS DynamoDB. В мене вона використовується в продакшені, хоч і іграшковому — в ній зберігаються коментарі до мого блогу (дивіться ось тут.) Для коментарів обрав через те, що на таких обсягах вона безплатна, а також щоб не хостити базу самостійно. Хоча насправді головна її перевага, це те, що DynamoDB практично не має обмежень в масштабуванні, та, обравши її для проєкту, можна ніколи більше не піклуватись про швидкодію.
Уважний читач запитає — не має обмежень в обмін на що? У випадку DynamoDB така величезна перевага забезпечена величезним компромісом — простотою запитів. Замість бази в DynamoDB є таблиця. Записи у таблиці — обʼєкти довільної форми. Тут все як звичайно у NoSQL. Але дістати записи можна або тільки за єдиним атрибутом — ключем розподілення, або ж за діапазоном значень другого атрибута — ключа сортування. Щоб була хоч якась гнучкість, додатково можна створити копії таблиці з тими самими даними, але іншими ключами — вторинні індекси. Причому переіндексація неможлива без перестворення таблиці чи індексу. Тому чим DynamoDB найбільше відрізняється від нормальної бази — тим, що необхідно якнайкраще продумати схему запитів замість схеми даних.
Наприклад, для моєї системи коментарів первинний індекс такий: ключ розподілення - URL сторінки, ключ сортування - ID коментаря (ID коментарів в мене впорядковані за часом). Таким чином я можу вибрати з таблиці всі коментарі для заданої сторінки. Це головне, що потрібно для додатка. Але з такою схемою неможливо знайти коментар за його ID, не знаючи URL. Тому є ще вторинний індекс, у якому ID коментаря — вже ключ розподілення. Якби я хотів сторінку коментарів за автором, то додав би ще індекс за автором.
Зрозуміло, що такий підхід влаштує не кожний додаток. Головне, що треба забути про довільні запити, як до бази SQL. Тож навіть адміністративної панелі на кшталт ActiveAdmin не зробиш — треба всі запити планувати заздалегідь. (Технічно, в DynamoDB ще є можливість фільтрувати результати запитів за довільними критеріями, але це робиться перебором, та коштує так само як нефільтрований запит. До речі, платити доведеться за обсяг прочитаних та записаних рядків.)
Але насправді у DynamoDB великий потенціал, що розкривається через кмітливо розроблену структуру індексів. Якщо хочеться дізнатись більше, раджу цю книжку, в ній такі приклади розбираються, що самому дуже важко було б доперти.

