Стендап Сьогодні
Що я зробив, що я хочу зробити, і що це все значить.
Повсякденні здобутки в форматі стендапу.
Детальніше в статті
Підписатись на RSS
📢
Канал в Telegram @stendap_sogodni
🦣
@stendap_sogodni@shevtsov.me в Федиверсі
23.05.2024
Публікація в Mastodon: світлини та архітектура
🖼️ По вчорашньому питанню з форматом ілюстрацій вийшло ось що: по-перше, хоч пости пишуться в Markdown, але розмітка для зображень заборонена. Що, взагалі, абсолютно логічно. Тож залишається два підходи: або світлину окремим постом як в Telegram, або включати світлину в головний пост. В головному пості вона зʼявиться наприкінці, але все одно так мені більше подобається.
🚧 Ще для повноти функціонала мені потрібно редагувати пости, тобто синхронізувати пост в Mastodon з тим, що в блозі. Як це вже працює для Telegram: я зберігаю для кожного поста (з блогу) його ID в Telegram, а також контрольну суму змісту. Якщо збережена контрольна сума розбігається з актуальною, то викликаю API редагування посту. (Насправді там навіть не одна, а дві контрольні суми. Одна — від змісту, що безпосередньо надсилається в Telegram. Друга — від вхідного файлу. Вона використовується, щоб не обробляти файли зайвий раз.)
🚢 Все це рішення хотілося б опублікувати, але зупиняє те що немає красивої історії розгортування. Скрипти я запускаю вручну, а потім комічу результати. Хотілося б щоб публікація відбувалася автоматично. Ймовірно, під час генерації статичного сайту. Якби оце розвʼязати, то можна було б перетворити купку скриптів на продукт.
22.05.2024
Mastodon: публікація через API
Хотілося б ретранслювати цей канал в Mastodon, але ж в концепції WOPE (Write once - publish everywhere.) В Телеграм я давно публікую ботом, також весь зміст є на сайті, доведеться й для Mastodon зробити автоматичну публікацію.
В цілому це набагато простіше, ніж з Telegram або з Twitter. У GoToSocial є API, з ним все зрозуміло, працює без сюрпризів. На власному сервері жодних обмежень на довжину поста немає. Навіть в Markdown можна писати.
Але ж мої пости пишуться не просто в Markdown, а містять метадані. Також я використовую особливу розмітку для посилань на пости з каналу. Можна або, як то кажуть, обробити регулярками по-простому, або все ж доведеться розібрати Markdown, перетворити та зібрати назад. Знайшов рендерер саме для цього.
Та друге питання — що робити з ілюстраціями. Наразі вони публікуються в Телеграм окремим постом через особливості відображення постів зі світлиною, які мені не подобаються. В Mastodon можна або робити так само, або обʼєднати в один пост; треба ще поекспериментувати та визначитись. Якщо окремим, можна робити мінітред з двох постів.
21.05.2024
AWS Lambda для запуску скриптів
Зазвичай про Lambda згадують в контексті всяких конфігурацій Serverless, тобто хочуть заміняти ними справжні сервери. Ну або для інтеграцій з іншими сервісами, наприклад, як обробник черги.
Але, за що я люблю Lambda: це найпростіший спосіб запустити код в AWS. Так, може я виходжу з позиції, коли базова конфігурація вже є в Terraform: ролі, мережа, і таке інше. Але нічого простішого я не знаю та лямбди чудово виконують ролі разових чи запланованих задач.
Ключем є можливість задеплоїти Lambda відвантаженням ZIP-файлу. Навіть з вебінтерфейсу. Особливо в поєднанні з Go це зводить деплой до секунд: скомпілювати, створити архів, відвантажити. Бо програми на Go легко скомпілювати локально та результат не буде відрізнятися від “чистої збірки” на CI. На відміну, наприклад, від Ruby. Хотфікси для Lambda можна розгортувати вручну (хоч не заохочую таку поведінку.)
Також Lambda можна запустити з вебінтерфейсу. Функція ця називається “Test”, але нехай то не збиває з пантелику: такий тест не відрізняється від іншого запуску. Тут навіть можна передати параметри; в моїх лямбдах часто будуть особливі ключі запуску: без ключа вона виконує головний намір — наприклад — за планувальником, а з ключем переходить в ручний режим та робить щось особливе — наприклад, перевірку або повне оновлення, або ще щось.
20.05.2024
Пара відкриттів з керування задачами та GTD
Поки налаштовував задачі в OmniFocus, зʼясував дві важливі речі. Як і з усім, корисно було порозглядати відео від справжніх користувачів.
🎯 Обовʼязково формулювати кожний проєкт як закінчуване твердження. Для цього потрібно додумати цей проєкт та зрозуміти — в цьому моменті — що ти від нього хочеш. Якщо не додумати зараз, доведеться думати щоразу як бачиш проєкт. Коли недодуманих проєктів пʼятдесят, їх сенс втрачається та система розвалюється.
Наприклад: висів в мене декілька років проєкт “Прибрати гараж”. (Зазвичай навесні зʼявляється, а потім поки доберуся, ба — вже знову холодно та не на часі.) Змусив себе подумати та переписав як “Бути задоволеним порядком у гаражі”. (Ну, бо дійсно — немає обʼєктивного критерію тут, ідеальним гараж ніколи не стане.) Та відразу стало зрозуміло, як його просунути: продати шини, замовити вивіз сміття, і так далі.
📝 Нарешті зрозумів силу контекстів. “Контекст” по GTD - це категорія обставин, в яких можливо зробити задачу. Я до них ставився як до звичайних тегів для фільтрації. Але в чому сила: кожний контекст утворює окремий список задач. Ключовий момент, що в нього йдуть тільки ті задачі, які готові до виконання.
Під час планування розкидуємо задачі, які пора робити, по контекстах. Коли є час на задачі, обираємо контекст — а з нього наступну дію. Відповідно, для всього, що ми ще не збираємося робити, контекстів не потрібно. (Взагалі, в моделі GTD фільтрів не могло бути, бо все робилося на папері. Контексти й були, буквально, списками задач. Але з цифровізацією цей нюанс втратився.)
19.05.2024
Mastodon та селфхостінг
Здається, я нарешті припинив дивитися та вирішив отримати акаунт у Федіверсі. Акаунт поки таємний (хоч знайти його дуже легко.) В цьому пості буде мова не про користувацький досвід, а про адміністрацію. (Хоча пишіть свої акаунти, обовʼязково підпишусь.)
Я дуже довго намагався відмовитись від власного сервера; проте ніяк не міг обрати, кому ж довірити акаунт. Як з поштою, в теорії можна привʼязати акаунт на власному домені до сервера десь ще.
На жаль, на відміну від пошти, акаунти Mastodon жорсткіше привʼязані до технічної реалізації, тому перейти з одного серверу на інший буде проблематично. Технічні параметри твого сервера зберігаються на інших серверах, та протоколу їх оновлення поки немає. А раз так, довелося налаштувати власний сервер, щоб в майбутньому не залежати не від кого.
…Тут проблема: Mastodon написаний на Ruby on Rails. Хоч я й працюю з Rails щодня на роботі, хостити великий застосунок самотужки (та ще й за власний кошт!) не хочеться прямо ніяк. Але, Mastodon це тільки найвідоміша реалізація протоколу ActivityPub. З альтернатив обрав GoToSocial - він націлений на особисті сервери (наприклад, в ньому зовсім немає реєстрації.) Також GoToSocial написаний на Go. Для селфхостінга це повна протилежність Rails: споживає мінімум ресурсів та тривіально деплоїться.
Під час деплою в fly.io + Cloudflare нічого незвичайного не робив. GoToSocial може працювати з базою SQLite, тобто окремого серверу бази не потрібно.
Чого не очікував: сервер живе доволі активним життям! Достатньо засвітитися в глобальній мережі, та починаєш отримувати нескінченний потік активностей. Що ще раз підтверджує, що не варто було встановлювати собі “справжній” Mastodon.
18.05.2024
OmniFocus
OmniFocus - це Jira у світі менеджерів задач для платформ Apple. В сенсі, не найкрасивіший (то буде Things), але найпотужніший. Так само як і Jira, OmniFocus є насамперед базою даних про задачі, з якої можна ліпити те, що влаштовує твої потреби.
Як і Jira, OmniFocus існує дуже довго (я перший раз його встановив у 2012) та як і Джіру, я його недолюблюю за надмірну складність. Проте коли в тебе сотні проєктів, великих та малих, то простими вони не виглядатимуть ніде.
Мої останні спроби зберігати проєкти були в власному плагіні для Obsidian; вимушений зізнатися, що не дочекаюся, поки я його завершу. Так, Ідея розробити систему та зробити під неї спеціалізований менеджер задач мені все ще подобається. В теорії зробити такий менеджер легше, ніж загальне рішення — бо набір функцій обмежений. Але річ у тім, що експериментувати з такою спеціалізованою системою стає надто дорого. Тому спробую експериментувати далі в готовому середовищі OmniFocus.
Нарешті, щодо систем та великої кількості задач. Зрозумів, що коли задач стає багато, то вони стають ніби дозволом нічого не робити (принаймні, проактивно) через відчуття марності. Тому критично важливо відокремити абсолютний мінімум поточних задач від решти. Причому їх кількість повинна залежати не від навантаження (яке за природою необмежене), а від можливостей.
17.05.2024
Перевірка унікальності в OpenSearch
…А немає її! В ті чи інші причини. Певно, головним чином тому, що індексація відбувається асинхронно, а до індексації перевірки не буде.
Проте є один метод, перевірений часом. Це зробити унікальний ключ ідентифікатором. Таке працює в багатьох NoSQL базах, наприклад, в DynamoDB практично лягає в основу. Тільки з міркувань рівномірного розподілення значень в OpenSearch краще брати не прямо ключ (скажімо, URL сторінки), а хеш від нього.
(Взагалі підхід з використанням справжніх значень як ідентифікаторів називається “натуральні ключі” та був популярним в часи “голих” SQL баз. А з приходом ORM як головного методу доступу — занепав.)
Ідентифікатори в OpenSearch, звісно, унікальні. Але й тут криється нюанс - звичайна операція індексації не заборонить повторюваний ідентифікатор, а просто перезапише документ (тобто зробить “upsert”). А нам потрібна операція create
.
Я вже натрапляв на проблему в тестах, що згенеровані фабрикою документи час від часу збігалися ідентифікаторами, вставлялися без create
, та призводили до випадкових помилок.
16.05.2024
Коли DRY не працює
Поділюся сьогоденним рефакторингом, яким дуже задоволений.
Історія така. Є розділ застосунку (насправді ActiveAdmin), де в багатьох місцях будуються адреси деякого ресурсу. Це в Rails робиться легко, так й код чистий.
Нововведення таке, що цей ресурс може існувати як самостійно, так і вкладений в інший ресурс. На кшталт такого: були просто “заклади”, а тепер зʼявилися у них власники; заклади власника можна переглядати окремим списком — проте загальний список теж залишився.
Задача: коли переходиш з власника на його заклади, а потім, наприклад редагуєш та зберігаєш — то маєш опинитись знову на списку закладів власника. (А якщо з загального списку — то повернутись туди.)
Ніби все просто та є навіть вбудована можливість зробити вкладеність ресурсів на рівні маршрутів. Але… тепер кожне місце, де будується адреса, повинно зʼясувати в якому ми режимі та побудувати або /owners/1/places/2
, або /place/2
.
Перша спроба розсипала по коду відповідні розвилки if
- що негайно засмутило Rubocop, та й вочевидь мало поганий вигляд. Замінити розвилки єдиною функцією (тобто класично “підсушити” код) немає можливості, бо вони відрізняються начинкою — маршрути всюди різні.
Тоді придумав взяти ті if
та витягнути всі в окремий модуль. Ну й нехай в ньому три майже однакових методи — зате тепер вони семантично сполучені. Читачам буде легко зрозуміти їхню мету, а може навіть пізніше порефакторити краще.
Отже, якщо вже доводиться задля нової логіки вносити побічні зміни в багато місць коду, нехай вони будуть стислими та легко розпізнаними.
15.05.2024
Масове видалення обʼєктів з AWS S3 та Google Cloud Storage
Сьогодні стикнувся з несподіванкою: якщо для видалення бакета AWS S3 Terraform примушує його спочатку спорожнити вручну, то з Google Cloud Storage робить те ж саме автоматично. Видалення може не тільки тривати днями, а й дуже дорого обійтись.
З першого погляду обидва сервіси не беруть плати за видалення об’єктів. Але є нюанс: спочатку треба дізнатись їх перелік. А це вже нормальна платна операція. Добре коли перелік є ззовні — може, в базі — але це не завжди так. Чим менш охайно та обережно пишуть в бакет — тим дорожче буде його почистити. Ось така пастка хмарного сховища.
Вихід, який я можу запропонувати, це правила життєвого циклу. Видалення обʼєктів за правилом дійсно безплатне. Цим можна скористатися при видаленні бакета: достатньо додати правило про видалення через 1 добу. Це застосується й до тих обʼєктів, що вже існують на момент створення правила. Щоправда, правила не виконуються миттєво та доведеться почекати — проте видалення вручну теж процес не швидкий.
Правила життєвого циклу — корисна штука. Єдине, що вони розглядають кожен обʼєкт окремо, тому не можна висловити, наприклад “залишити 1000 останніх файлів”. Зате можна розмежовувати правила за шляхом та за тегами, та навіть за розміром файлів — є де докласти фантазію.
14.05.2024
Відстеження кофеїну
🤎 Після перегляду ось цього відео вирішив задля забави встановити собі застосунок для стеження за кофеїном - HiCoffee. Треба сказати, що я й так відповідально ставився до кави принаймні не пив її після шостої. Бо під кофеїном я засинаю ще більш-менш, але прокидаюся декілька разів на ніч.
…Отже. Найбільшим відкриттям з застосунку було те, що період напіврозпаду для кофеїну - 5 годин. Цифру я цю знав, але не усвідомлював; точніше, в моїй уяві було так: за пʼять годин до сну кави не пити.
А тут завдяки графіку в застосунку я зрозумів, що насправді на час сну в організмі залишається 1/8 ранкової кави, 1/4 обідньої та 1/2 вечірньої. Якщо підсумувати, виходить майже ціла порція кави перед сном! Одним словом, за типовий день кофеїн накопичується швидше, ніж виводиться.
Все це, очевидно, дуже приблизно та абстрактно. Але дозволяє зрозуміти у відносних кількостях, як на тебе впливає кава, та коли пора зупинятись. (Звісно, не тільки кава, а й кола, чай, енергетики та так далі.) Для мене дуже корисний експеримент.
Також хочу відзначити, що HiCoffee здатний скорелювати споживання кофеїну з даними з Apple Health. Мені поки рано робити висновки, але вже якимсь чином є слабка кореляція високого споживання та коротшого сну. Отакої.