TJ Ilya Chekalsky
4 776

Основа 2.0

Changelog и технический post-mortem перезапуска.

В закладки
Аудио

На самом деле написать чейнджлог у меня не выйдет. После пары месяцев записывания того, что мы поменяли во второй версии Основы, я понял, что проще будет записать то, что осталось как раньше. Вот так выглядит сравнение двух версий на Github — 3109 изменённых файлов, 300 000 изменённых строк (но часть из них, конечно, технические).

Основа — это платформа, на которой сейчас работают сайты Комитета: vc.ru, DTF и TJ. Мы начали писать её два года назад, в ноябре 2016 года. Тогда каждый из трёх сайтов имел собственный движок. Баги в каждом нужно было исправлять отдельно, фичи реализовывать по несколько раз. Очевидно, долго так продолжаться не могло.

В 2017 году начался переезд всех проектов на Основу — сначала DTF, затем TJ и потом vc.ru. Так мы добрались до начала 2018 года — и у нас накопилось много вещей, которые хотелось бы изменить. Первая версия движка не предусматривала никаких разделов, кроме заранее захардкоженных — для каждого зачастую была какая-то своя логика (чего стоила Аляска, не попадающая в ленты). Параллельно на vc.ru стало появляться всё больше страниц компаний, которые требовали создание новой сущности — с возможностью вселяться в неё сотрудникам.

В этот момент неосторожное предложение технического отдела «так давайте сделаем одной сущностью пользователей, компании и подсайты» дало рождение новой версии вашего любимого сайта. Вместе с этим вакансии, сделанные как MVP на коленке за месяц, стали одной сущностью вместе со статьями. Аналогично поступили и со статичными страницами вроде правил сайта — раньше это было просто html-файлы. Теперь их можно верстать в редакторе силами любого сотрудника, необязательно привлекать для этого разработчиков.

В общем, вторая версия Основы унифицировала всё, что у нас к тому моменту было, заложив фундамент для будущих функций. Параллельно мы попытались решить накопившиеся проблемы. Изначально идея была в том, чтобы просто переписать то, что есть, те места, которые нам с точки зрения программистского перфекционизма не нравились. Мы планировали уложиться в меясяц-полтора.

Часть задач, вынесенных на рефакторинг

Когда мы обсудили новую структуру данных с подсайтами и компаниями стало понятно, что времени это займёт больше — к счастью, нас никто не торопил, все понимали, что мы фактически переписываем целый сайт. Но тогда ещё никто не представлял, какой он большой.

Отвлечёмся на секунду и я расскажу, что такое Подсайт и Контент. Это две основополагающие сущности всего сайта. Подсайт — это всё, что генерирует или содержит Контент. То есть с точки зрения базы данных никакой разницы между пользователем, компанией или подсайтом нет. Каждый из них может быть как автором контента, так и его владельцем.

Например, когда я пишу этот пост, в поле creator_id будет проставлен мой id, а в поле owner_id — id подсайта «TJ», в который я и пишу. Но я могу изменить creator_id на id «TJ» и тогда «TJ» напишет сам в себя — так тоже можно. Или можно взять компанию и написать от её имени в любой подсайт — тогда она будет отображаться в качестве автора. Как вы уже догадались, это значит, что технически каждый пользователь может писать сам в себя — так мы получим личные блоги.

Если я сотрудник Комитета и хочу от имени компании написать пост на vc.ru мне нужно в неё вселиться. Мы разрабатывали это по аналогии с фейсбуком, где можно комментировать или лайкать от имени своих страниц. Теперь у нас можно так же. Поэтому нам пришлось отделить подсайты (пользователей, компании) от их логинов, и каждый логин может вселяться в неограниченное количество подсайтов, которые ему подвластны. Ширяев, например, может вселиться в подсайт Сломалось и ставить вам лайки по всему TJ. Для этого ему не придётся как-то отдельно логиниться, он просто переключит аватарку в шапке.

Когда мы реализовывали вселение, мы столкнулись с такой проблемой — когда пользователь покупает подписку на TJ, то подписка должна привязываться к логину или к подсайту?

Если привязать к подсайту, то когда человек вселится в аккаунт своей компании, ему придётся покупать подписку ещё раз, чтобы от её имени написать комментарий. Довольно спорная механика. Решили привязать к логину, посмотрим, что из этого выйдет.

Отдельной проблемой на Основе 1.0 для нас были комментарии. Вообще, начать рассказывать надо с того, как у нас работало кэширование. А работало оно так: все страницы сайта были закэшированы на уровне nginx, а персональные данные вставлялись с помощью ajax-запросов. Это позволяло держать любую нагрузку (если мы где-то не косячили) — пользователю моментально показывалась страница из супербыстрого кэша, а потом догружалась аватарка в шапке, оценки постов и комментарии. Всё было хорошо, пока мы не за***лись инвалидировать этот кэш и писать бесконечные запросы, чтобы отобразить хоть сколько-нибудь динамичную фигню — в противном случае она могла закэшироваться на час.

Ну и не проходило недели, чтобы кто-нибудь не жаловался на медленно загружающиеся комментарии. А когда происходило что-то вроде учёбы в Англии, наступал просто конец — и стало понятно, что никакие отговорки про несовершенные браузеры нам не помогут — нужно было грузить комменты с бэка вместе с телом страницы, а это значило распрощаться с нашим прекрасным кэшированием (которое мы хотели даже заопенсорсить, но не успели).

Вместе с этим мы имели неосторожность сообщить Денису, что персональные ленты, раз уж мы отказались от кэша, сделать не очень сложно. Тут и родились подписки на подсайты, и как вы понимаете, наши месяц-полтора начали потихоньку растягиваться.

В общем, зарелизили мы вторую версию Основы на DTF только в конце мая. Вскоре после этого vc.ru начал задыхаться без функциональности компаний — пришлось менять привычный уклад и перезапускать во вторую очередь его. Это дало такой буст, что следующие пару месяцев мы релизили множество новых фич, отлаживая механизмы работы ленты и всяких настроек, с которыми вот и приехали на TJ.

На самом деле вторая версия Основы отличается от первой практически каждой строчкой кода — когда мы создавали первую версию Основы мы не знали, куда нас это приведёт, и основной фичей для нас была возможность иметь одну платформу для трёх сайтов. Спустя два года мы имеем огромную платформу с внушительным списком функций. Когда мы релизили DTF 2.0 нужно было сделать код-ревью всему новому коду. Я садился и пытался просто файл за файлом прочитать код проекта в поисках багов и мест для оптимизации, и в конце дня я понимал, что не дошёл даже до середины — количество кода просто огромное.

В общем, мы немного передохнём и снова двинемся вперёд — у нас огромное количество ещё не реализованных фич, и мы не собираемся останавливаться. Подробнее о текущих изменения и о наших планах мы напишем отдельно.

Спасибо ребятам из нашей великолепной команды разработки:

Паша, Мурод, Гоша, Абдужаббор (бэкенд)

Петя, Артём, Мика (фронтенд)

Слава, Кирилл, Макс (мобильные приложения)

Валера и Женя (спецпроекты)

Александр, Лёша и Костя (дизайн)

Влад, Филипп, Денис и Орзик (продукт и менеджмент)

{ "author_name": "Ilya Chekalsky", "author_type": "editor", "tags": [], "comments": 154, "likes": 153, "favorites": 38, "is_advertisement": false, "subsite_label": "team", "id": 81131, "is_wide": false, "is_ugc": false, "date": "Thu, 06 Dec 2018 12:49:53 +0300" }
Комментарии

Абсолютный Артем

36

Давайте все-таки засунем vc и d*f в подсайты tjournal, чтобы восстановить справедливость во имя всего

Удачный Валера

10

А могли просто поставить Вордпресс и не париться.

Краткий супер_стар

3

Илья, есть ли возможность по ссылке из прямого эфира идти в нормальные коменты, а не в одну ветку?

Условно то, что есть сейчас это потому что иначе упадет сервер, или прихоть Ширяева (бла бла про старые компы типа пихто, которые еле ос загружают)?

И еще, почему вместо прежнего прекрасного цитирования сделали вот такое (в чем причина)?

TJ
дискуссии в сообществе доступны только владельцам клубного аккаунта
С клубным аккаунтом вы сможете
создавать записи и вести дискуссии в закрытых сообществах
наслаждаться нашим сайтом без рекламы
помочь проекту и почувствовать себя лучше
Купить за 75₽

Прямой эфир

[ { "id": 1, "label": "100%×150_Branding_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox_method": "createAdaptive", "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "ezfl" } } }, { "id": 2, "label": "1200х400", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "ezfn" } } }, { "id": 3, "label": "240х200 _ТГБ_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "i", "ps": "cndo", "p2": "fizc" } } }, { "id": 4, "label": "240х200_mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "i", "ps": "cndo", "p2": "flbq" } } }, { "id": 5, "label": "300x500_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "ezfk" } } }, { "id": 6, "disable": true, "label": "1180х250_Interpool_баннер над комментариями_Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "ffyh" } } }, { "id": 7, "label": "Article Footer 100%_desktop_mobile", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byswn", "p2": "fjxb" } } }, { "id": 8, "label": "Fullscreen Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "fjoh" } } }, { "id": 9, "label": "Fullscreen Mobile", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "fjog" } } }, { "id": 10, "disable": true, "label": "Native Partner Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyb" } } }, { "id": 11, "disable": true, "label": "Native Partner Mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyc" } } }, { "id": 12, "label": "Кнопка в шапке", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "fdhx" } } }, { "id": 13, "label": "DM InPage Video PartnerCode", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox_method": "createAdaptive", "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "cndo", "p2": "flvn" } } }, { "id": 14, "label": "Yandex context video banner", "provider": "yandex", "yandex": { "block_id": "VI-223677-0", "render_to": "inpage_VI-223677-0-130073047", "adfox_url": "//ads.adfox.ru/228129/getCode?pp=h&ps=cndo&p2=fpjw&puid1=&puid2=&puid3=&puid4=&puid8=&puid9=&puid10=&puid21=&puid22=&puid31=&puid32=&puid33=&fmt=1&dl={REFERER}&pr=" } }, { "id": 15, "label": "Плашка на главной", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byudv", "p2": "ftjf" } } }, { "id": 17, "label": "Stratum Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "fzvb" } } }, { "id": 18, "label": "Stratum Mobile", "provider": "adfox", "adaptive": [ "tablet", "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "fzvc" } } } ]
Оперативные новости со всего мира
Подписаться на push-уведомления