Стендап Сьогодні
Що я зробив, що я хочу зробити, і що це все значить.
Повсякденні здобутки в форматі стендапу.
Детальніше в статті
Підписатись на RSS
📢
Канал в Telegram @stendap_sogodni
🦣
@stendap_sogodni@shevtsov.me в Федиверсі
15.06.2023
Сучасний стан розробки на ClojureScript
На Реддіті побачив запитання про засоби перевірки OPML файлів для RSS. Ба, думаю, так я ж такий писав. От тільки давно. Та є два нюанси. По-перше, він був розміщений на моєму виділеному сервері, який я давно припинив підтримувати (бо складно). По-друге, написаний він був на Clojure/ClojureScript, бо в ту епоху (у 2015) мені було цікаво кудись його застосувати.
Куди розмістити зараз — в мене вибір один - Firebase. Бо дешево та просто. Але Firebase на бекенді підтримує тільки JavaScript. Не проблема, в теорії, бо бекенд можна портанути з Clojure на ClojureScript. Знайшов гарну інструкцію, як запустити ClojureScript на Firebase Functions, та це дійсно швидко спрацювало.
До переписування бекенду я поки не дійшов, бо ще треба оновити фронтенд. Майже все, що я використовував 8 років тому, померло. Зʼявилися нові інструменти. Замість Figwheel для збірки проєктів тепер є Shadow CLJS. Дуже приємно працює, з простими налаштуваннями робить дві збірки — бекенд та фронтенд, сам завантажує залежності (зі світу Clojure; ті, що на Javascript, завантажує yarn, як звичайно), в браузері наживо оновлює. По цьому питань взагалі нема.
Фреймворк для фронтенду Om теж більше не підтримується. Вони самі рекомендують переїхати на Fulcro. Це дуже складна система зі власними абстракціями та з привʼязкою до свого фреймворку на бекенді. В мене найбільше питань по тому, що для вибірки даних зі стану використовується EQL. Для простого додатка це зайві ускладнення.
Зате re-frame все ще живий. Re-frame це як React+Redux+Reselect в красивій функціональній абстракції. Його я б і рекомендував брати, якщо захочеш спробувати Clojure. Це, напевно, найкрутіше що є з практичних міркувань.
Для форматування коду мені дуже подобався parinfer, але й він більше не підтримується. Для розробки в VSCode є доповнення Calva з власним форматувальником — до нього треба звикнути, але задачу балансування дужок, в цілому, він виконує.
14.06.2023
WaitGroup в Go
Для закінчення питання, поставленого вчора, не вистачає ще однієї частини. Ну, добре, зробили ми архітектуру на контекстах, контекст сплинув, горутіни отримали сигнал зупинки. Що далі? Необхідно дочекатись, доки всі горутіни завершать свою роботу. Особливо якщо зупиняємо всю програму — якщо не чекати, то немає сенсу навіть ввічливо попереджати горутіни про зупинку.
Можна знову придумати свою систему з каналами, і так далі. А можна взяти стандартний тип sync.WaitGroup, який створений саме для того, щоб чекати зупинки декількох горутін. Від банального лічильника його відрізняє наявність методу Wait()
, який буде чекати, поки всі горутіни не викликають метод Done()
.
Тобто алгоритм таких: на початку підраховуємо кількість горутін, які запускаємо, та заряджаємо викликом wg.Add()
. Далі, кожна горутіна по завершенню викликає wg.Done()
. Нарешті, головна горутіна спочатку сигналізує про завершення контексту, а потім викликає wg.Wait()
.
Чи не надто витратно створювати WaitGroup для довготривалих процесів? Ні, цей тип містить лише 2 цілих числа, та не має “живого” коду. Взагалі це просто лічильник + семафор, нічого магічного. Це добре, бо нам потрібно передати WaitGroup в кожну горутіну, яку ми запускаємо.
Як чекати з обмеженням по часу? Це типова задача — наприклад, ми знаємо, що через 60 секунд після отримання сигналу наш процес буде вбитий оркестрантом. Відповідь така: обмеження треба обробляти ще всередині горутін. Що це значить на практиці — залежить від конкретного випадку. Але ми точно повинні не кидати горутіни у невизначеному стані, як воно буде, якщо тайм-аут спрацює назовні.
Такий підхід набагато простіше, ніж спостерігати за спустошенням каналів з чергами або вигадувати ще якийсь механізм очікування.
13.06.2023
Контексти в Golang
Як зупинити код у відповідь на зовнішній фактор? Один з механізмів відомий всім — то команда kill
, якою можна зупинити цілий процес. Але, як зробити це всередині програми? Що робити, коли блок коду займає більше часу, ніж ми можемо чекати? Це реальні питання, які часто не мають гарної відповіді. Ось в Ruby, наприклад, є модуль Timeout
, який наполегливо рекомендують не використовувати.
В Go питання зупинки процесів стає ще актуальнішим, оскільки створення одночасних процедур — типова повсякденна робота. Як зупинити всі ті горутіни, коли вони більше не потрібні? Можна накрутити (та я й крутив) додаткові канали для сигналізації. Зупиняємо сервіс — сигналізуємо горутінам.
…Паралельно з цим доводиться постійно передавати в різні бібліотечні функції якийсь “контекст”. Нащо він потрібен той контекст — не знаю. Добре що завжди можна створити новий на місці, наприклад функцією context.Background()
.
Та тільки нещодавно зрозумів, що контексти в Go і є той самий механізм зупинки коду у відповідь на зовнішній фактор. У контексту є метод ctx.Done()
, який повертає канал, що буде закритий, якщо пора зупиняти код. Для перевірки використовується команда select
. Це й треба використати замість самописних механізмів. Більше в документації.
Щоб створити власний корисний контекст, є відповідно функції context.WithCancel
та context.WithTimeout
. Особливо зручно те, що такі функції загортають контекст батьківського рівня, та успадковують закриття ще й від нього.
Для сигналів, про які я вже згадав, є signal.NotifyContext. Сервіс, який себе гарно поводить, має спиратись саме на цей контекст, щоб контрольовано зупинити всі свої компоненти.
Тепер ніяких більше context.Background()
.
12.06.2023
Сумний стан української локалізації
Коли я сьогодні дізнався, що Cyberpunk 2077 невдовзі отримає українські субтитри, зрадів. А потім, захотів зрозуміти, який взагалі на 2023 рік стан локалізації. Вирішив зробити маленьке дослідження самотужки.
Звідки взяв дані. Відразу обрав як джерело Steam, щоб якось обмежити вибірку. Теоретично, каталог Steam відкритий для всіх, та є сервіси на кшталт SteamDB, які його викачують. Але саму базу для аналізу довелося ще пошукати, бо стягнути її не дають, а потрібного мені функціоналу пошуку не вистачало. Нарешті знайшов на Гітхабі версію на грудень 2022 року. Далі написав скрипт на Ruby, який генерує CSV з результатами. Далі — робота редактора таблиць.
Результати, на перший погляд, прикрі. Тільки 1746 ігор загалом перекладені українською. У відсотках це лише 8%. Менше, ніж російською або польською. Але більше ніж, наприклад, тайською — при тому, що в Таїланді живе 70 мільйонів людей.
(Цю цифру складніше отримати, ніж можна уявити. З ігор треба викреслити всі, що не мають локалізації зовсім — зазвичай це ігри англійською або китайською. До того, як це зробив, спостерігався різкий спад локалізації у 2014 році. Це пояснюється запуском програми Greenlight, за якою випустити гру в Steam стало набагато простіше.)
Якщо ж дивитися на значення в динаміці, то картина краща. З року в рік кількість ігор українською зростає. З ігор, що вийшли у 2022 році, перекладено було 10%. Взагалі бачу дві групи мов: є “класика” локалізації — французька, німецька, італійська, іспанська — ці мови втрачають долю локалізації. А менш представлені мови — як корейська, норвезька або українська — поступово її збільшують. Все це можу пояснити тенденцією до мовної інклюзивності.
А з українською озвучкою все зовсім погано. Хоч в базі значаться близько 500 ігор, насправді більшість з них практично не має озвучки як такої. Реально можна порекомендувати хіба що серію Metro 2033 та всі частини Сталкера. Та, як не дивно, першу частину Baldur… ее, Брами Балдура. Оце справжня, міцна RPG. Та вся озвучка перекладена. Я спочатку й не повірив, довелося встановити та перевірити. Звісно, голосу в Брамі мало, зате тексту як в добрій книзі. Одним словом, рекомендую.
11.06.2023
Які RSS я читаю?
Поступив запит на рекомендації по RSS. Раніше я писав про те, як я користуюсь RSS взагалі. Складно давати рекомендації по конкретних стрічках, бо фактично через RSS можна споживати майже все, що вам цікаво в інтернеті, але все ж таки висвітлю дещо з того, на що я підписаний.
-
Моя власна стрічка з Hacker News. Тут завжди багато цікавого. Зокрема, на HN можна знайти багато маленьких авторських блогів, на які теж варто підписуватись.
-
З великих IT-видань - The Verge, MacRumors. Ще Lifehacker та Wirecutter. Ще є гарний Ruby Weekly. Про ігри давно читаю Rock, Paper, Shotgun.
-
Купка стрічок додатків та сервісів, якими я користуюсь. Якщо в когось є живий блог, додаю. Все так просто. Наприклад, цікаві блоги у GitHub та Cloudflare.
-
Окрема категорія - RSS стрічки з GitHub Releases; так можна відстежити оновлення, які треба робити вручну. От, наприклад, Hugo: https://github.com/gohugoio/hugo/releases.atom.
-
Декілька вебкоміксів: Saturday Morning Breakfast Cereal, Penny Arcade, Oglaf. Ну XKCD ще.
-
Купа персональних блогів. Нещодавно знайшов блог творця Agile Programming. Або є Павло Авдокушин — чудовий оглядач української інфраструктури. Але загалом персональні блоги нечасто пишуть та їх більше сотні, тому не можу тут зробити чесний огляд.
-
Блог Railsware. :) В нас зараз серйозна команда блогерів, яка висвітлює внутрішні підходи, тож виходять цікаві статті, особливо з галузі керування продуктами.
10.06.2023
Рімейк System Shock
В мене з System Shock смішна історія. Перший раз я про цю гру почув десь у 2001 році, та витратив може місяць, щоб викачати її через модем зі швидкістю 56.6К. На жаль, мене чекало тільки розчарування, бо користуватися архаїчним (вже на початок сторіччя) інтерфейсом не зміг. Після години чи двох спроб гра була закинута.
За минулі 22 роки я встиг пограти у всі нащадки System Shock - від System Shock 2 та Deus Ex до Dishonored та Prey. Тому, коли у 2016 році відкрився Kickstarter для створення рімейку, то я підтримав його без роздумів. На розробку пішло 7 років, але нарешті рімейк вийшов.
Та вийшов пречудовим! По суті це абсолютно нова гра, яка близько відтворює рівні та сюжет оригіналу. Вочевидь багато чого змінено; насамперед темп гри змінився абсолютно, та, я так розумію, довелося переосмислити озброєння та противників. Тепер це повноцінна бродилко-стрілялка з інвентарем, за формулою дуже нагадує Prey.
Основний геймплей залишився — поступово та методично досліджувати просякнуті атмосферою та подібні до лабіринтів рівні, поки не відкриєш всі двері, не знешкодиш всі камери, та не збереш все що варте збору. Ніяких елементів RPG тут немає, успіх визначається тим, скільки спорядження встигнеш зібрати. Цікаво, що можна обрати, більше чи менше інструкцій про сюжет ти будеш отримувати. На складності за замовчуванням вони високорівневі та необхідно уважно слухати аудіозаписи та роздивлятись оточення.
Чи рекомендую я System Shock Remake? На всі 100! Чи хороша це гра сама по собі? Так, чудова.
Тепер з ігор, в які я б дуже хотів пограти, але не можу через архаїчність, залишається Fallout 1 та 2. Може, і їх дочекаюсь. А ще все ж таки хочеться тепер спробувати оригінал System Shock, або принаймні Enhanced Edition.
09.06.2023
PostgreSQL vs Elasticsearch
Поступив запит: чим Elasticsearch краще за PostgreSQL. Спробую сформулювати. Наперед скажу, що питання скоріше не чим, а де або для чого.
Постгрес — це база даних загального призначення. Вона вміє все. Та з кожною новою версією ще більше. Якщо порівнювати суто по можливостях, то з PostgreSQL можна робити що завгодно. В цьому його головна перевага. Якщо з чогось починати проєкт, то Постгрес найкращий вибір, завжди (якщо в бюджеті є місце для сервера бази даних, звісно.)
Єдине, що PostgreSQL робить гірше — це масштабується. Рішення для горизонтального масштабування існують, проте коли вертикальне (збільшення машини) не розв’язує задачу, то, на моєму досвіді, всі обирають поміняти базу. Наскільки вистачить однієї машини — залежить від того, що потрібно зберігати. Для облікових записів користувачів — напевно, вистачить назавжди. А для, скажімо, щосекундних аналітичних метрик — може й для старту буде мало. Бо як БД загального призначення, у PostgreSQL доволі обмежені здібності оптимізувати під задачу.
Як я вже писав, для вирішення сучасних потреб в масштабуванні зʼявилися бази даних NoSQL. В їхньому числі й Elasticsearch (так, як я вже писав, Elasticsearch - справжня база даних.) В серці кожної NoSQL бази сидить компроміс: так, вона масштабується, але характер використання буде обмежений. Тому, при виборі NoSQL бази, треба дуже уважно дивитись, що вона вміє, та чи не буде вам потрібно щось інше.
Elasticsearch вміє класний складний пошук та агрегації. При цьому його легко масштабувати як на запис, так і на читання. Як приклад того, що він робить погано: поєднання документів на кшталт JOIN
. Тобто в базі мають сидіти документи, які нас цікавлять самі по собі.
Такий режим використання гарно себе показав для всілякої журнальної інформації, тому зараз більше можна побачити Elasticsearch як базу даних для журналів, ніж як пошуковий рушій (бо, якщо все, що вам потрібно — це повнотекстовий пошук — то його чудово вміє робити Postgres.)
На останнє, не раджу читати абстрактні порівняння вигляду “знайди 10 відмінностей”. “PostgreSQL - реляційна база даних. Elasticsearch - документна” і так далі. З таким підходом в сучасних базах (та й взагалі технологіях) швидко загубишся. Щоб обрати базу, треба розуміти, що вона робить краще інших, та може ще важливіше — чого ніяк не робить. А якщо є сумніви — беріть PostgreSQL. :)
08.06.2023
Кілька думок про Docker Compose
Сьогодні був день Docker Compose. Як я вже писав, в нас багато на нього навішано. Взагалі, як на мене, якщо вам доводиться працювати над системою складніше, ніж класичний LAMP-стек, то варто опанувати Docker Compose та відтворити на ньому архітектуру.
-
Софт, запакований в Docker, не завжди працює так, як написано в документації. Різні постачальники Docker-образів можуть по-різному налаштовувати один та той самий софт — інколи це буває корисно, інколи шкодить, але головне памʼятати, що розбіжності існують та поглядати на вихідний Dockerfile. Є й софт, який взагалі на Docker не розрахований та працюватиме погано або ніяк.
-
Цілком можливо мати декілька проєктів в одній великій мережі сервісів. Для цього треба явно задати мережеві налаштування. Це зручно, коли маємо справи з декількома репозиторіями, та хочеться
docker-compose.yml
тримати біля проєкту. -
Відкриття дня — в графічному інтерфейсі Docker для macOS надзвичайно зручний інспектор запущених контейнерів. Тут не тільки можна фпереглянути логи та налаштування, а й навіть зазирнути в файлову систему — причому кращого способу це зробити я не знаю. Реально вже сьогодні дізнався нового про свої контейнери (а саме, що варто вичищати логи після збірки.)
07.06.2023
Kafka
Тиждень тому я писав про важливість перенесення навантаження з критичного шляху. А також про те, що це вирішується чергами. Черга надає можливість передати роботу з одного сервісу до іншого. Але є проблема — черга це труба о двох кінцях. Нам обовʼязково доведеться створювати споживача “в пару”. Черга створює жорстку звʼязку сервісів.
Apache Kafka розв’язує цю проблему. Це дещо середнє між чергою та базою даних. Як в черзі, дані організовані в послідовність повідомлень. Як в базі даних, ці повідомлення надійно зберігаються миттєво після приймання, та не видаляються після їх прочитання та обробки. Категорія сервісів, до яких належить Kafka, називається брокер повідомлень. Один сервіс (або сервіси) повідомлення пише, інший (або інші) читають - все з надійним посередником посередині.
Як на мене, то в першу чергу Kafka корисна тим, що дозволяє високонавантаженому сервісу максимально швидко писати дані, без того, щоб відразу розробляти архітектуру їх обробки. Це й спрощує розробку, й підвищує надійність, і взагалі в наш час Big Data розкриває нові можливості збирати те, що незрозуміло як використати.
Але є й інші переваги. Kafka може роздавати одній й ті самі повідомлення декільком споживачам — наприклад, сьогодні вони потрібні тільки в базі, а завтра, може, зʼявиться сервіс аналітики.
Також є прості, але можливості обробляти дані всередині Кафки, наприклад, рахувати їх, або обчислювати кінцевий стан сутності по журналу змін - Kafka Streams. Та Kafka Connect - інструмент для завантаження даних з Кафки до звичайної бази даних або ще кудись.
Єдине, що мені не подобається — все воно написане на Java, з усіма особливостями конфігурації та розміщення сервісів на Java.
06.06.2023
Перша засада гарної доповіді — думай про аудиторію
Сьогодні слухав на роботі презентацію про те, як робити презентації. Причому фокус був на робочих дзвінках, які є повсякденністю для нас всіх. Задумався, які поради я можу додати зі свого боку.
На мою думку, головне, про що треба думати при плануванні доповіді (формальному плануванні, чи в голові за пʼять хвилин — це вже як піде) - це аудиторія. Бо предмет робочої доповіді нам зазвичай добре відомий. Але що з нього розказати? Я нерідко бачу, як люди закопуються в деталі, які нікому окрім них не зрозумілі, або навпаки, зазначають, що за два тижні рівно нічого цікавого не відбувалось. Тому, щоб підготувати себе, пропоную пару питань:
-
Що аудиторія знає? Наскільки вона володіє контекстом? Чи це люди, з якими ти працював вчора, або навпаки, далекі від проєкту? Чи знають слухачі місцевий жаргон? До якої спільної бази можна привʼязати предмет доповіді?
-
Чого аудиторія хоче? Тут може бути багато варіантів, як не дивно. Може хочуть більше деталей та обґрунтувань. Або отримати загальну картину. Або відчути, що є прогрес та ситуація під контролем. Так чи інакше, наша доповідь має відповідати потребі слухача, або нас просто не будуть слухати, свідомо або несвідомо.
З таким фокусом в голові вже можна підходити до предмета доповіді та планувати, на яких аспектах можна зупинитись. А ще зорієнтованість на аудиторії сприяє рапорту більше, ніж правильний кут камери або уникнення слів-паразитів.
Раніше: про логічні ланцюги.