Канал
У Льоні сьогодні
Нотатки архітектора систем та майстра на всі руки. Що я зробив, що з того вийшло, і що це все значить.
-
Як дістати перелік залежностей для проєктів на Ruby, JavaScript, Golang
💎☕🐹 Закінчив зі збором залежностей для всіх трьох моїх головних мов - Ruby, JavaScript, Golang. Виявилось, що для Ruby було складніше за все.
В JavaScript залежності перелічені в файлі
package.json, який як звичайний JSON легко прочитати. Далі є API npm.jshttps://api.npms.io/v2/package/:packagename, звідки дізнаємось домашню адресу пакета. (До речі, і цей API, і API RubyGems відкриті, бо всі їми користуються кожного разу, як встановлюють пакети.)В Go залежності містяться в файлі
go.mod. (Принаймні, в сучасному Go, бо раніше було декілька альтернатив, а зараз все стабілізувалось.) Файлgo.modнестандартного формату, але не складніше, ніжGemfile.lock. До того ж оскільки в Go назва пакета — це адреса його репозиторію, то ці адреси ми дізнаємось безпосередньо.Залишилось трохи причепурити та можна випускати у світ.
Весь скрипт написаний на Ruby, бо взагалі такі аналітичні штуки мати приємний вигляд саме цією мовою. Але, скажете ви, а як же ж купа запитів до API? Хіба не краще було їх паралелізувати, як то пропонує підручник по Go? А на Ruby паралелізувати операції, що блокують можна не гірше, практично в один рядок. Це тільки якщо у вас складні обчислення, то Ruby погано підходить, бо він фактично однопроцесорний.
-
Почав проєкт для автоматичного виставлення зірок на GitHub
😺⭐💎 Через відсутність світла робота не дуже йде. Почав як вправу маленький проєкт, який давно крутився в голові: GitHub Autostar
В чому суть. Всі ми любимо оцінювати проєкти на GitHub за кількістю зірок. Але ж хто ті зірки ставить? Я сам нечасто про це згадую. Тож виходить дивна асиметрична оцінка.
Щоб виправити цю ситуацію, я хочу зробити скрипт, який знаходить в моїх проєктах всі прямі залежності, що є на GitHub, та автоматично проставляє їм зірочки. Це можуть бути Ruby-геми, пакети NPM, модулі Go тощо. Навіть закладки чи нотатки. Так без зайвої ручної праці можна спрямити несправедливість оцінок.
Тепер трохи о реалізації: поки зробив прототип для Ruby. Спочатку ідея була така, щоб застосувати можливості Bundler для інтроспекції залежностей. Головна проблема з цим те, що щоб воно працювало, треба відтворити правильну версію Ruby для кожного проєкту, а також встановити всі залежності. (Також бракує документації по внутрішньому функціоналу Bundler.)
Тому схилився до статичного аналізу. Перша ідея: розбирати
Gemfile. Але ж гемфайл — це фактично скрипт на Ruby, та хоч в гемфайлах зазвичай дотримуються визначеного формату, очікувати можна на все. Втім, знайти регулярками рядки виглядуgem "foo"досить просто.Але потім нарешті роздивився структуру
Gemfile.lockі знайшов там розділ, де перелічені прямі залежності проєкту (а саме,DEPENDENCIES.) Цей формат файлів створений для машинної обробки та — хоч він і не стандартний — прочитати його набагато легше, ніжGemfile. Як результат, в робочих проєктах першим способом знайшлось 146 гемів, а другим - 150.Після цього залишається звернутись до відкритого API RubyGems -
https://rubygems.org/api/v1/gems/#{gem}.jsonта дізнатись домашню адресу кожного гему. А потім, перевірити, чи спрямована вона на GitHub.Так отримав 128 репозиторіїв, що, порівняно зі 114 зірочками, що я поставив вручну за довгі роки користування Гітхабом, вже досить багато.
Наступні кроки — реалізація для інших мов, та пошук простого рішення для масової роздачі зірок.
-
Гаджети, що допомагають за відсутністю світла
💡🔌⚡ Саме цікаве за сьогодні це те, що нарешті цілий вечір немає світла. Тож розкажу, які гаджети допомагають з цим поратись.
-
Налобна лампа (Petzl Tikkina 2) на трьох батарейках AAA. Найнижча яскравість тримає 16 годин. Зазвичай в моїх лампах стоять акумулятори (Panasonic Eneloop). Але якщо немає, то батарейки нескладно здобути та зберігати. Налобна лампа — то найзручніший ліхтарик для активностей, бо підсвічує там, де дивишся, і не займає рук.
-
Ліхтарик Brennenstuhl PL 200 A - довго шукав такий “неформатний” ліхтарик, і нарешті випадково побачив у колеги. Завдяки формфактору його пристебнути до одягу чи до рюкзака — це я й шукав — але також за магніт можна повісити на різноманітні поверхні. Світить дуже яскраво.
-
Павербанк на 20000 мАч (від Baseus). До того всі мої павербанки були близько 5000 мАч, бо такі легше носити. Але ж маленький павербанк є “одноразовим”, потім треба заряджати. Двадцять тисяч — це зовсім інший рівень свободи. Їм можна користатись багато годин, не обмежуючи себе. Але ж заряджається він також кілька годин, навіть на найміцнішій зарядці у 18W.
-
Лампа від USB (в мене від Xiaomi, але їх безліч). Вона працює від того самого павербанка і світитиме за моїми підрахунками десь 30 годин. Це на найвищій яскравості, коли вона майже замінює нормальне освітлення.
-
USB-роутер з 4G та Wi-Fi, що я покупав для машини, але тепер його можна вставити в той самий павербанк та мати мобільний інтернет для всієї родини з набагато меншими витратами енергії, ніж якщо роздавати з телефона.
-
Макбук M2 Air. :) Останнє, про що доводиться перейматись — це чи вистачить батареї для роботи.
-
А щоб ноутбук працював довше, раджу софт - AppTamer, щоб обмежити активність додатків при роботі від батареї та TripMode, щоб так само обмежити використання мобільного інтернету. Обидва доступні з Setapp.
-
-
Наше ставлення до ситуації обирати нам
Сьогодні з сином годину шукали по крамницях конкретний різновид мівіни. В найближчому “АТБ” такого не виявилось. Оскільки це було ввечері, то крамниці — як виявилось — були закриті. Тож, повернувшись до “АТБ”, та постоявши в черзі пізніх покупців, отримали ту саму мівіну, що могли б забрати відразу і без черги.
(До речі, чи знаєте ви, що саме “Мівіна” - власний український бренд миттєвої локшини? Принаймні, був, поки його не купив Nestle. Тому, всю миттєву локшину я наполегливо називаю мівіною, а ніяк не ролтоном чи дошираком.)
Урок, запропонований сином — варто йти на компроміси, замість пошуку ідеального рішення. Що ж, це так. Особливо цінно, що цей висновок був не навʼязаний.
Але, як на мене, то можна подивитись на ситуацію інакше. Прогулянка — сама по собі задоволення. Ще й разом. Ще й зараз, коли вулиці такі темні, що місто стає сюрреалістичним, лімінальним вже о восьмій годині вечора.
Чи було це безцільне бродіння в темряві, або чудова вечірня прогулянка? Вирішувати нам.
-
Просте та дешеве кешування для скриптів зі збереганням на AWS S3
💭🗃️🧠 В генераторі стрічок я використовую цікавий підхід до кешу. А саме, як кеш я використовую звичайний файл на S3.
Кеш потрібен здебільшого для того, щоб не завантажувати одну й ту саму сторінку два рази. Бо коли для кожного поста в стрічці треба робити окремий запит, повторювати ці запити дуже не хочеться.
Колись цей генератор був звичайним вебдодатком на Sinatra. Тоді для кешу в мене був Memcached. (Так, це було дуже давно.) Але потім мені набридло витрачати гроші на хостинг додатка на Ruby, і я переробив генератор на AWS Lambda, яка запускається раз на добу, а результат зберігає на статичний хостинг S3. Таке рішення виходить повністю безплатним.
Залишилось тільки питання — що робити з Memcached? Очевидна відповідь — сервер AWS ElastiCache - коштує гроші. Та до того ж нераціонально тримати цілий сервер для декількох хвилин на добу. Тоді я і придумав рішення з S3.
Найпростіша база даних — то завжди є простий файл. В цьому випадку, файл у форматі JSON, що містить ключі кешу та значення. Окрім самих значень, я також зберігаю термін придатності — так кеш не буде зростати нескінченно.
Перед запуском скрипту я завантажую кеш та видаляю значення, для яких вибіг термін, а по закінченню — зберігаю назад на S3. Тут можна подивитись код.
Можу уявити й складніші рішення на такому самому підході — наприклад, можна було зберігати повноцінну базу SQLite.
-
Покращення повнотекстової стрічки Hacker News
📰🖼️🧼 Вчора я тільки здув пил зі свого генератора стрічки; сьогодні доробив справжню красоту.
В більшості спирався на чудовий гем metainspector. Він вміє знайти на будь-якій сторінці метаінформацію - заголовок, опис, ілюстрацію. Причому знайти різними способами - наприклад, опис може взяти і з стандартної розмітки, і з розмітки OpenGraph, і просто з першого параграфу сторінки. Завдяки цьому гему вдалося збагатити стрічку базовою інформацією про публікацію, щоб легше було зрозуміти, чи цікава вона.
Також зі сторінки коментарів зробив витяжку трьох топових коментарів - також щоб відразу зрозуміти, чи цікава була дискусія. Власне, тепер моя стрічка більш зручна, ніж сам Hacker News, оскільки дозволяє на одному екрані побачити як підсумок публікації, так і коментарів до неї!
До рядка з базовою інформацією (оцінка / кількість коментарів / адреса / автор) додав позначки-емодзі. Так легше сканувати цю інформацію. Насправді, був здивований, наскільки легше.
Нарешті, збільшив кількість постів на добу до 60 - тобто двох перших сторінок головної. Так виходить 420 постів на тиждень - розумна кількість.
-
Покращення для моєї RSS-стрічки для Hacker News
🎨🗞️☕ Нарешті покращив RSS-cтрічку для Hacker News. Це один з найкращих ресурсів для айтішних новин та цікавих проєктів. Але його інтерфейс не підходить для читання раз на тиждень. Ще є багато альтернативних клієнтів для HN, з яких можу порадити hckr news, але ж мені потрібна RSS, і не просто RSS, а зручна.
Поки що стрічка просто містить топові пости з головної сторінки за минулий день. Далі мій RSS-агрегатор буде збирати пости за кожен день в загальну стрічку. Чому пости за минулий день? Тому, що топові пости можна обирати тільки з тих, що вже проіснували достатньо, щоб бути побаченими.
Стрічка доступна за адресою: RSS. Вона розміщена на AWS S3 і не має правильного сертифіката — тому
http. Також, стрічка оновлюється скриптом раз на добу, тому її хостинг коштує умовно нічого (Тільки, будь ласка, не зловживайте.)Друге покращення — вирішив, що тексти (Markdown) не обовʼязково писати у моноширинному шрифті, та поміняв шрифт на Helvetica. Власне, я вже багато років час від часу експериментую з пропорційними шрифтами. Та й зараз мій головний шрифт для коду — пропорційний Input Sans. У родині Input є, звісно, і моноширинний шрифт. Я вживаю його для мов, де вирівнювання рядків має значення — наприклад, для Go. У VS Code взагалі можна поміняти шрифт окремо для будь-якого формату файлів. (Чого не можна зробити — це поміняти родину шрифту для окремого типу символів, наприклад, коментарів.)
Додатково зробив так, щоб у Markdown була обмежена довжина рядка. Теж зручно для редагування текстів.
-
Cкладнощі з тестуванням БД на Go
🐹🗄️😭 Поскаржуся на складнощі з тестуванням БД на Go.
Попередження: мені ще не доводилося використати жодну з повноцінних ORM для Go. Причина в тому, що в мене завжди десь поруч Rails, а у Rails чудовий інструментарій для міграцій і такого іншого. Тож на долю Go залишається тільки обмежена кількість запитів. Тож записуємо їх явно, у вигляді SQL, а запускаємо за допомогою database/sql. Але ж їх теж треба тестувати.
Також я знаю про існування sqlmock, що замінить всю базу цілком. Це зручно, але самі запити ніяк не перевіряються, а це, з мого досвіду, сама ризикована частина. Тож будемо тестувати на справжній базі.
Спочатку треба відтворити структуру бази для тестів. Якщо є Rails, то це просто — беремо базу від Rails. Також для CI копіюємо
database_structure.sqlз Rails в репозиторій з Go, і завантажуємо перед тестами. Теж нескладно (тільки доводиться вручну підтримувати в актуальному стані.)А далі — складна частина. Як наповнити тестову базу даними? В Go немає загально прийнятного аналогу factory_bot - принаймні, такого, що можна вжити без ORM.
Раніше я наповнював базу довжелезними SQL-скриптами - на кшталт
TRUNCATE ...; INSERT .... Їх жахливо читати та змінювати. До того ж в скрипті незрозуміло, де важливі значення, а де — необхідне наповнення обовʼязкових стовпчиків. Втім, саме такий підхід я вживав багато років на декількох проєктах — бо принаймні він технічно простий.Потім все ж таки вирішив знайти щось розумніше і натрапив на бібліотеку testfixtures. Вона відтворює підхід Rails з фікстурами — тобто той, від якого практично всі відмовляються на користь фабрик. Не ідеально, але все ж набагато легше у підтримці, ніж SQL скрипти.
Бібліотека
testfixturesдозволяє описати таблиці у вигляді YAML. В цих файлах YAML можна навіть використати шаблони, та передавати значення з коду Go. Тобто замість непрозорих, магічних значень тепер в тестах можна посилатись на ті ж самі змінні, що будуть записані в базу. Чого не вистачає — автоматичного наповнювання обовʼязкових стовпчиків.Так поки й живемо. А ще налаштування бази зручно робити з testify/suite.
-
Система пошуку в інтернеті Kagi - мій новий пошукач
🔍🦮🎩 Сьогодні несподівано поміняв свій підхід до пошуку в інтернеті.
Я вже багато років вживав як базовий пошук DuckDuckGo. Для мене головна його перевага — це так звані bang-команди, що дозволяють відразу делегувати пошук на інший сайт — наприклад,
!g fooшукатиме в Google, а!yt bar- на YouTube. Сам по собі пошук у DuckDuckGo кепський, бо власного індексу він не має, а шукає через Bing. (Тому мого блогу в DDG не знайти.) Але, можливість легко перестрибнути в більш доцільний пошукач мене полонила.Але. Колега порадив пошукач “нового покоління” Kagi. За який треба платити $10 на місяць. Що ж такого він пропонує за ці гроші? Вочевидь, гроші за підписку — гарантія (або обіцянка) того, що пошукач не торгуватиме твоїми даними. (А ще спробувати до 50 запитів можна без оплати.)
Крім того, сподобалась можливість налаштувати пошук під себе — вийняти сайти, що не подобаються, або навпаки, підняти деякі догори. Та й сам по собі пошук добре працює. Хоча Kagi також веб не індексують, а делегують запити різним системам, в тому числі й Google. (Так що тут мій блог знайдеться.) На перший погляд здається, що низькоякісні статті Kagi ховає, але тут ще подивимось.
Як щодо bang-команд, то Kagi їх підтримує. Але я вирішив піти ще далі, та знайти локальну заміну. Бо як DDG, так і Kagi перенаправляють bang-команду зі свого сервера, а локальна утиліта піде напряму. Так я знайшов доповнення для Safari xSearch - це буквально те що треба. Працюватиме xSearch і на айфоні.
Тут є проблема — в Safari не можна додати власний пошукач. Тому як Kagi, так і xSearch вдаються до хаків, перехоплюючи запити до стандартно обраного в Safari пошукача. Це працює непогано, але не дуже акуратно.
Отже, я вирішив піти до кінця та залучити додаток, що в мене вже є - Alfred. Єдине що, треба перевчитись писати пошукові запити туди, а не в браузер.
-
Obsidian, погана синхронізація через iCloud Drive, та хороша через Obsidian Sync
🪨☁️🔄 Obsidian розчарував з синхронізацією через iCloud Drive, але з цього можна винести гарний урок.
Головна проблема в тому, що на iPhone файли з iCloud завантажуються помітно повільніше, ніж локальні файли. Через це уповільнюється пошук по файлах — а це найважливіша в мобільній версії функція. Якщо ж немає надійного підключення, то все стає ще гірше, бо наявність локальної копії файлів з iCloud Drive не можна гарантувати.
Одним словом, для синхронізації iCloud Drive погано підходить. Як хмарне сховище для файлів — добре, але якщо потрібна швидкодія — ні.
Тому довелось заплатити гроші та перейти на Obsidian Sync - їхній власний сервіс. Має end-to-end шифрування, тобто на сервері нотатки прочитати неможливо. Нотатки, що синхронізуються з Obsidian Sync, розташовуються у звичайній локальній директорії, та ніякої неоднозначності з їх наявністю немає. Як на телефоні, так і на компʼютері пошук працює швидше.
До речі, поставив собі питання, як це Bear, яким я користався раніше, не має такої проблеми, хоч і синхронізується через iCloud. Виявляється, що тут синхронізація побудована на хмарній базі даних CloudKit, а не на iCloud Drive. Тобто якщо будувати свій додаток з синхронізацією, то теж краще дивитись в бік CloudKit. Проте, в Bear нотатки не мали вигляд звичайних файлів — довелося обирати або одне, або інше.