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

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

Підписатись на RSS · 📢 Канал в Telegram @stendap_sogodni

08.08.2024

Оптимізація структур даних Go в памʼяті

В продовження вчорашньої ситуації: ділюся декількома знахідками.


07.08.2024

Використання памʼяті в Go

Намагаюся знизити розмір величезної структури даних на Golang. (Назвемо її “базою даних в памʼяті.”) Вона більше не влазить в памʼять, відповідно, є сенс знизити витрати, а не просто палити гроші на неоптимально використані ресурси.

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

До того, всі складені типи займають деяку кількість зайвого місця. Структури містять вирівнювальні байти. Масиви мають резервну місткість. З типом map все взагалі погано, бо його нутрощі нам недоступні, та ми практично не можемо дізнатись, яка в словника резервна місткість. Але вона є: дуже грубо кажучи, Go резервує місце під кількість елементів, кратну ступеням двійки.

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

Пишу маленький аналізатор витрат. Поки що мені вдалося “пояснити” десь 60% тих витрат, що повідомляє ReadMemStats. Чи є 40% надлишком на керування памʼяттю? Хочеться, щоб ні.


06.08.2024

Значки-посилання для статичних сторінок

Певно, всі бачили ті кольорові значки в описах проєктів на GitHub - ті, що ведуть на документацію, показують статус збірки та інше. Вони не тільки виглядають нівроку, а ще й виконують критичну функцію: додають краплю динамічності до статичної сторінки.

Звідки ті значки беруться? Робити їх власноруч — навіть статичні — трохи занадто. Тому що є готові сервіси — вони здатні не тільки згенерувати значок, а й додати до нього динамічний зміст.

Великих сервісів два. Shields.io - популярний та старий. Badgen - зʼявився як заміна для Shields, але так і не витіснив попередника. Shields.io підтримують більше сервісів та мають кращу документацію. Навіть можна взяти дані з власного JSON API, або навіть сторінки HTML!

Ось, я тільки що зробив значок для цього каналу. Хоч Shields.io не підтримує Telegram, але я можу отримати кількість підписників з вебсторінки каналу, передати її в Dynamic XML, витягнути потрібний блок через XPath, та ще й додати логотип Telegram у вигляді власного SVG (в Shields.io є логотип Телеграму, але надто мілкий.) Чудовий результат без коду та без інфраструктури.

Такий значок мені буде корисний на сайті, бо там така сама проблема, як з GitHub: він статичний. Взагалі хто памʼятає, в епоху Web 1 - тобто до соціальних мереж — вже існувала схожа технологія — інформери. Це теж були картинки, які збиралися на сторонньому сервері. Два типових приклади — це лічильних відвідувачів (коли ж я останній раз такий бачив?) та віджети з погодою (на власному сайті погода? просто метеоцифрова магія!) Єдине, що помінялося тепер: значки генеруються у SVG, а значить, не потребують від сервера більше зусиль, ніж звичайна маленька вебсторінка.


05.08.2024

GTD: успіх?

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

Цього разу вирішальним елементом є ведення проєктних матеріалів на канві. Канва виявилась найкращим компромісом між легкістю та виразною здатністю. Раніше я нотатки завжди робив текстом або вкладеними списками — та вони з розміром втрачають осяжність. У великій канві також важко орієнтуватись, але: завдяки розташуванню в просторі, легко помітити підрозділи, які пора винести на окремий аркуш.

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

А коли на канві є плани у всіх необхідних подробицях, то список задач вільний містити тільки справжню наступну дію. З цим успіх перемінний, але я докладаю зусиль. Наприклад, читаю дію “зробити фічу X” та ловлю себе на думці “треба буде перевірити як це зробили в Y”. Значить, або відразу перевірити (та ймовірно записати в канву), або записати це як наступну дію. Такий процес для GTD життєво необхідний, та я радий що він не захламлює список задач (бо в ньому записана тільки безпосередньо наступна дія.)

Список задач я наразі веду в найпримітивнішій формі в Apple Reminders… я буквально ще не бачив схожої за простотою реалізації. Але то можна розглянути окремо.


04.08.2024

Homebrew Cask на практиці

Цими днями підʼєднав до Homebrew Cask всі встановлені застосунки, які там є. Вийшло аж 55! Навіщо воно потрібно?

(Homebrew Cask - це додаток до Homebrew, який містить звичайні графічні застосунки. Працює саме так, як уявляєш.)

Як я це бачу, найбільша перевага навіть не в тому, що застосунки легко встановити — бо я щоразу налаштовую новий компʼютер переносом системи та такої потреби навіть не стає. А в тому, як їх легко оновлювати. Homebrew Cask містить скрипти для повністю автоматизованого встановлювання навіть там, де воно зазвичай потребує діалогу — наприклад, для Zoom. Навіть MacUpdater так не вміє. (Хоча його теж рекомендую.) Та й звісно всі застосунки можна оновити однією командою — теж гарно.

В HomeBrew Cask не можна додати застосунки з App Store. Але сьогодні дізнався про утиліту mas для роботи з App Store через командний рядок. Так можна зберегти список застосунків та встановлювати автоматично. Хоча мені навіть більше подобається можливість провести аудит.

А з чим гірше, так це Setapp. За все хвалю цей сервіс, проте автоматизації йому бракує. Поки кожний застосунок доведеться встановлювати вручну. Шкода — за вісім років існування могли б вже щось зробити. Навіть стандартної для macOS автоматизації через AppleScript або Shortcuts немає. (Зате AI помічник є. Пріоритети нашого часу!)


03.08.2024

Емоції та думки

Абсолютно незаплановано рівно рік потому повертаюсь до теми емоцій. Також незаплановано мені сталося послухати дві книги про “поліпшення настрою” з досить схожими назвами: Feeling Good та Letting Go та схожими оцінками на Amazon та Goodreads. Обидві обговорювали емоції та думки. А головний збіг те, що ці дві книги розкривають тему з діаметрально протилежних боків.

Feeling Good ставила тезу: “навʼязливі погані емоції — це наслідок хибних думок.” Всі наші емоції є продуктом автоматичних міркувань. Через аналітичну роботу з думками можна виправити вади міркувань (наприклад, схильність перебільшувати проблеми), а коли негативні думки зникнуть — то з ними й емоції.

А Letting Go, навпаки: “погані думки — це наслідок законсервованих поганих емоцій.” Непрожиті емоції накопичуються та створюють постійне напруження, а з ним — і думки. Людину з законсервованим злом все буде злить. Людина з образою всюди знайде несправедливість. Через усвідомлення та проживання можна позбавитись накопичених емоцій та тоді ті самі обставини будуть викликати більш позитивні міркування.

Як може бути, що обидва підходи, вочевидь, працюють? Гадаю, тут немає суперечності: думки та емоції існують пліч-о-пліч та утворюють петлю зворотного звʼязку. До того ж одним людям легше працювати з думками, іншим — з емоціями. Чудово знати, що в тебе є вибір.


02.08.2024

SMTP vs Email API

Я вже колись писав про те, який SMTP повільний та як там дивно реалізоване шифрування. В цілому, якщо ви надсилаєте пошту через сервіс та він підтримує HTTP API (як Mailtrap), та клієнт теж здатний надсилати по HTTP, то так і треба робити.

Але сьогодні передивлявся питання про наш сервіс з StackOverflow та викрив ще одну, дуже важливу причину надсилати пошту через HTTP API. Порти, через які надсилають пошту, будуть скоріше заблоковані.

Стандартний порт SMTP 25 взагалі блокують майже всюди, бо саме цей порт використовується для отримання пошти, а значить — це єдиний спосіб розсилати спам. Для підключення з клієнтського застосунку на сервіс надсилання пошти використовуються інші порти - 587 та 465. Але і вони дуже часто будуть заблоковані про всяк випадок — хоча надіслати пошту безпосередньо отримувачу за цими портами неможливо.

Надійний спосіб — це дозволити клієнтам надсилати через якийсь “неофіційний” порт — наприклад, 2525. Я гадаю, що так і треба робити, якщо є можливість, щоб уникнути подальших проблем. Проте все одно гарантій немає. Деякі хостинги (та системні адміністратори) заради безпеки попросту блокують всі порти, окрім необхідних. Та, виходячи з питань StackOverflow, це реальна проблема.

В той час як порти HTTP не заблокують на найсуворішому з хостингів. Тому забуваємо про SMTP та надсилаємо пошту безпечним та швидким API. (А ще краще взяти інтеграцію, яка все це абстрагує.)


01.08.2024

Просунуте використання Dash

Органайзер документації Dash це одна з незамінних для мене програм. (До речі, вона є в Setapp.) В базовій комплектації вона містить довідку по всіх популярних мовах та бібліотеках. Та це вже виправдовує користування нею. Мати документацію доступною миттєво та з контекстним пошуком — неоціненно.

В простому вигляді раджу призначити Dash до комбінації клавіш; в мене це Hyper+D. Так документація завжди під рукою. Але сьогодні захотів піти далі та інтегрувати Dash у VSCode. Інтеграція знає мовний контекст, тому відразу відкриває сторінку правильної мови. Хотілося, щоб вона також працювала за комбінацією Hyper+D… щоб цього досягти, залучив BetterTouchTool та створив там привʼязку “Hyper+D у VSCode = Ctrl+H” (комбінація пошуку з доповнення.) Так у VSCode активується доповнення, а в будь-якій іншій програмі - Dash напряму.

Окрім вбудованих пакетів документації, в Dash можна встановити документацію до будь-якого пакета з деяких мов (Ruby, Go, Python, …). Тоді по них можна нормально шукати, а не так, як звичайно буває в інтернеті.

Але ще цікавіше що документацію можна генерувати власноруч. Причому раніше для того було потрібно писати павуків та будувати базу SQLite, то зараз все суттєво спростилося: Dash вміє завантажити цілий сайт, а потім вже підчистити нашим JS/CSS. Нагадало, як на початку 2000-х завантажував всілякі енциклопедії програмою Teleport Pro.


31.07.2024

Розподілені транзакції в Sentry

Розбирався вчора з цікавою ситуацією з моніторингом продуктивності від Sentry. (Мікровідгук: в цілому мені цей продукт подобається, він хоч і не такий виточений як New Relic, але свою задачу виконує успішно.) Ситуація була в тому, що в проєкт насипалося забагато подій — а з кишені висипалася пропорційна сума грошей.

Зазвичай ми не зберігаємо прямо кожну операцію в Sentry. Це було б очевидно надто витратно. Для того є параметр traces_sample_rate - так можна знизити частоту хоч до кожної 100-ї операції, хоч до 10000-ї - як хочете. Також є можливість задати складніший алгоритм в параметрі traces_sampler: наприклад, можна зберігати тільки ті операції, що впливають на наше поточне дослідження продуктивності; або ті, що були надто повільними тощо.

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

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


30.07.2024

Власні віджети для AWS Cloudwatch Dashboards

В сервісі моніторингу AWS Cloudwatch є можливість вбудувати в дешборд не тільки графік чи журнал, а й абсолютно власний зміст. Віджет фактично є вікном до AWS Lambda-функції.

Хочу сказати, що це зручний спосіб надати обмежений доступ до ресурсів. Взагалі AWS Lambda добре підходять для інкапсуляції доступів. А в разі віджетів в нас ще й авторизація готова, та стилі, та й деякі особливості інтерфейсу: наприклад, можливість обрати діапазон часу, або увімкнути автоматичне оновлення.

Лямбда в віджеті може повертати довільний HTML/CSS… а чого вона не може, так це містити JavaScript. (От, сьогодні дізнався про елемент <summary>, яким можна згорнути блок без всякого JS.) Також віджет може містити внутрішню навігацію, але особливим чином: у вигляді спеціальних посилань на інші AWS Lambda. Оскільки посилання може йти на ту ж саму лямбду (з іншими параметрами), отримуємо можливість зробити маленький вебзастосунок.

Ось тут я стикнувся з проблемою… параметри до функції не зберігаються під час оновлення віджета — він скидається до початкового стану. Тоді знайшов, що хоч параметри не зберігаються, зате функція отримує ‘особливим параметром widgetContext стан форм, якщо такі є на віджеті. Тоді зробив помірно закручений код, де наявні параметри виводяться у <input type="hidden" /> - а якщо явних параметрів немає, тоді навпаки, дивлюся в зміст цього поля.