Технічний пост про свій проект із деталями, а не ще одна реклама (частина 1)

tl;dr Я прошу допомоги спільноти протестувати проєкт нашої соціальної мережі, про яку я вже писав, і взагалі таких тисячі — ця точно не злетить, чого ти паришся, чувак. Тому вважайте це щоденником розробників, де іноді будуть з’являтися різні кумедні штуки.

Вступ

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

Моя теорія в тому, що коментатори ДОУ токсичні, бо втомилися від булшиту в різних сенсах. Тому замість явного самовихваляння я спробую розповісти про те, що ми робили, і різні приколи розробки. Скажу відразу: вуха відкриті для будь-якої критики чи порад, адже наша робота — це щось на кшталт поетичних батлів.

Прикол № 1 для затравки

Коли ми тільки починали, у моментах, де я пропонував підтримку Markdown, фронтендери хрестилися і казали, що такого нема в класичних соцмережах, що при 0 користувачах ускладнювати немає сенсу й що мені треба більше відпочивати. Я погодився, тим паче що тоді мав основну роботу і ще одну, де працював за договором кілька годин на тиждень.

Але мені дуже хотілося, щоб посилання підтримувалися нативно: з прев’ю, внутрішнім обліком і всім таким. І ми додали концепт метаданих у код — бекенд, отримуючи новий пост, отримував також масив ідентифікаторів, затегованих у body за допомогою \u200B. Типу так: \u200B{1}. Фронтенд рендеріл текст вибираючи посилання з масиву.

Вийшло класно, ми навіть змогли робити прев’ю. Але виявилося, що:

  • Більшість популярних сайтів ненавидять запити з пулів хостерів. У відповідь ти отримаєш у кращому разі 403, у гіршому — класичний фолбек від Nginx на помилку 444.
  • Моя регулярка для пошуку посилань у тексті не врахувала, що люди люблять обгортати їх у дужки, а ще й самі посилання іноді містять дужки (привіт, Вікіпедія).
  • Посилання на самого себе не працювали, бо бекенд не бачив свій же домен.

Першу проблему ми вирішили кумедним костилем. Увесь сайт уже працював у Kubernetes на DigitalOcean, тож я просто додав проксі як фолбек: якщо запит падав, сервер пробував ще раз через мою власну квартиру. Це виявилося напрочуд ефективним. Для цього я взяв простий TinyProxy з вайтлістом запитів із сервера.

Проблему з дужками я вирішую досі, бо несповідимі шляхи користувачів. Нещодавно ми все-таки додали підтримку маркдауну, що додало головного болю, тому що поведінка рендеру на фронті виявилася непередбачуваною. Довелося піти на хитрість — тепер я спочатку перетворюю посилання з маркдаун на свій формат, а потім проходжуся по тексту як раніше.

Регулярка вийшла такою: (?:^|[\s(\[<\{'"`])(https://[^\s\}>'"`]+)(?:\s*<([^>]+)>)?

Третя проблема виявилася найгіршою. Попри допомогу одного з найталановитіших девопсів, яких я знав (і водночас одного з моїх найкращих друзів), ми так і не змогли змусити поди бачити власний домен. Довелося городити костилі.

На той час у нас уже працював окремий ендпоінт для побудови відповідей з тегами OG і всім, що робить посилання красивими. Я виніс його в окремий мікросервіс, і він став простим ререндером для таких запитів, повертаючи дуже простий HTML тільки з найважливішим. Можна було б заморочитися і зробити краще, але тоді навіщо я пишу цей пост?

Відео

О боже, як тільки з’явилися користувачі — усі захотіли відео. Але на це пішло 4 місяці. Спочатку ми додали обробку в Sidekiq з запуском ffmpeg, мінімум змін. Лімітували розмір файлу до 100 МБ, я потім додав перевірку тривалості й обмежив до 15 хвилин, але при такому розмірі це був уже другий презерватив, а не реально робочий план.

Та варто було відео бути трохи довшим за 5 хвилин або справді якісним — і ми зіткнулися з причиною, чому такі речі треба виносити в окремий інстанс, а не тримати в поді. Навіть за агресивних налаштувань у якийсь момент гувернер дивився на под, що жер 1000% ресурсів, поправляв монокль і підписував вирок. Стартували нові два, які знову брали завалений джоб, потім піднімалася нова нода — і так по колу. Мені вистачило мізків додати raise, інакше цей пост починався б із кредитної картки.

Поки я залишив усе всередині пода з Sidekiq, підняв ліміти, виставив гарантовані ресурси і змінив кодек на H.265 з профілем faster. Для тестових відео все пройшло успішно, викочуємо буквально днями — але я досі нервово заглядаю в k9s.

Росіяни

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

Майже відразу додали фільтри «Сховати пости російською мовою», що я вважав популізмом, але навіть у моєму особистому колі всі сказали, що це гарне рішення і я передумав. Зробили приховування на основі запитів в Google Транслейт API, копіюючи 20 відсотків посту рандомом з різних місць, методом точок акцентів, щоб точно отримати правильний результат навіть якщо цитується якийсь пропагандист.

По-перше, ми створили ідеальний ханіпот — трекали їхні сесії, намагалися заглянути за VPN, написали суворі правила й покладалися на користувачів, бо в українців (яких ми завжди вважали головною аудиторією) на них реакція, як у мого кота на апельсини.

У правилах було розписано багато, але коротко: крок вбік — публічний розстріл і похорон у морі. Дивіться самі: vmist.net/static/ref/rules

Та ще коли в нас і 50 користувачів не було, посипалися не просто боти, а реальні люди, які почали писати про кривавий режим і килимові бомбардування алеї ангелів. Довелося діяти швидко.

Наші гості користувалися нідерландським мікрохостером, створюючи там дешеві VPS. Я спершу думав, що це просто VPN, але вони реально логінилися туди і відразу заходили по RDS, бо в User-Agent часто була вінда. Написав купу листів хостеру, навіть нахабно погрозив судом, але отримав запевнення у сприянні та все на цьому. Чісто ООН чи как там.

На той момент у нас уже був бот Душнила, що працював на Gemini Flash 2.5, і я віддав йому на відкуп аналіз постів (згодом це переросло у велику інтеграцію, але про це в іншому пості). Він почав бити на сполох, вбивати акаунти і банити через Rack::Attack підмережі з коротким TTL. Я також заборонив вхід через сервіси миттєвих мейлів і синхронізувався з базами.

На цьому вони не зупинилися і почали штормити dev-оточення, яке я, на жаль, посадив на той самий домен, і знайти його було легко. Ви б бачили: пул пітерських IP 45.135.232.* буквально жив у мене на нетиповому порті SSH 2220. А ще був дев-сайт, відкритий назовні... Одного разу я не зміг через них швидко завантажити апдейт для Astrobot і додав knock, зроблений нашвидкуруч — тепер доступ відкривається тільки після правильної послідовності. Стало набагато легше жити.

Перший підсумок під постом

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

Історій у нас назбиралося на роки. Крім того, я постійно робив бенчмарки, ми зіштовхнулися з неймовірними проблемами інтегруючи Телеграм через їхній сервер у докері, ми придумали SSR усередині Rails API-only застосунку, я можу розсмішити будь-кого розповідями про проблеми React Native з Kotlin у рендері Webview і багато чого ще.

Крім відгуків, я прошу вас дати нам ще один шанс і подивитися на сам проєкт.

Вміст, vmist.net

З повагою до спільноти та щирою спробою розірвати цикл і почати писати цікаві технічні пости.

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

👍ПодобаєтьсяСподобалось5
До обраногоВ обраному4
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Технічний пост про свій проект із деталями, а не ще одна реклама

Ще одна реклама, технічних деталів трохи менше нуля.

Доречі,

я можу розсмішити будь-кого розповідями про проблеми React Native з Kotlin у рендері Webview

воно саме по собі — проблема, навіть без kotlin

А можна про дужки більш розкрито?

Припустимо, ми шукаємо у статті всі посилання, виключаючи все зайве, щоб замінити їх на метатеги. Для такого посилання нам потрібно врахувати всі можливі варіанти після ХТПС, описані в РФЦ www.ietf.org/rfc/rfc3986.txt

Серед дозволених символів є дужки ( і ), кома, точка і купа всього такого, що користувач може використовувати в реальному тексті.

Крім того, є наш власний синтаксис виду посилання <текст>, що додає рівень складності визначення патерну.

І ніби цього замало, є маркдаун, який спочатку перетворювався самим фронтендом, без участі метатегів. А це означає конструкції виду

[текст](посилання)

Що ж, маркдаун ми позбавляємося: ще до обробки проходимо по тексту і замінюємо всі такі посилання на попередній варіант.

Але що нам робити з чимось таким:

(https://en.wikipedia.org/wiki/Function_(mathematics)...😁)

І тут доводиться перекручуватися, перераховуючи все, що може бути виключеним останнім символом. Але раптом там не один, а, скажімо, три крапки? А емоджі (не повірите, як часто буває)? А якщо сам текст це код із екстраполяцією, де користувач просто забув вказати блок без форматування?

Біда ще в тому, що зі зростанням регулювання страждає і читабельність, і ефективність. Тому доводиться ділити це на модулі і робити покрокову обробку кожної проблеми. Це підвищує складність коду і вже баги.

Загалом головний біль.

А чого пробіли не рахувати після останньої дужки? А хоча можуть бути не тільки пробіли...кома, крапка, дві. Я б вирішив це через encode ще на етапі заповнення тексту.

Дуже вірна ідея, але складно реалізувати і ми витратили б місяць на фікси. Майже вся складна логіка тільки на беку, щоб швидше випускати версії з фічами. Користувачі більше радіють навіть глючним, але фічам, а не фіксам.

Моя теорія в тому, що коментатори ДОУ токсичні, бо втомилися від булшиту в різних сенсах

Ні, розписував раніше в темі про плагіат:

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

Ну, це теж, само собою. Я скоріше в цілому по палаті: типово ж, що пост «Я сделяль» майже завжди збере дружні поплескування по плечу в умовному американському твіттері і майже завжди глузування в нашому.

Можна зробити з цього висновки й запускати проєкти на міжнародну англомовну аудиторію спершу.

Підписатись на коментарі