company_banner

Post mortem: cледи за middleware или как мы сломали комментарии

    Привет! У нас не очень приятная новость: мы допустили ошибку в мобильной версии, которая могла вас побеспокоить все праздничные дни.



    Суть проблемы: человек отправляет комментарий к посту, видит его со своим логином и уходит со страницы, но если обновить страницу, этот комментарий будет уже под другим именем пользователя. Это работало только в случае, если пользователи одновременно находились на странице одного поста.


    По нашим данным, за выходные с мобильной версии было отправлено 774 комментария. Каждый из них мог пострадать.


    Немного технических подробностей

    Мы используем связку VueJS + NodeJS (Express, SSR).


    NodeJS обслуживает в один поток асинхронно сразу множество соединений, то есть использует один инстанс на всех клиентов. Это значит, что глобальные переменные инициализируются только один раз и живут до тех пор, пока жив инстанс.


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


    И вот что с нами случилось (это пример кода):


    global.foo = 'bar';
    
    app.get('/main', (req, res, next) => {
      res.send(global.foo);
    });
    
    app.get('/change', (req, res, next) => {
      global.foo = global.foo === 'bar' ? 'barbar': 'bar';
      res.send(global.foo);
    });

    Что вернёт сервер?


    • Клиент 1 на /main >>> ‘bar’
    • Клиент 2 на /change >>> ‘barbar’
    • Клиент 1 снова на /main >>> ‘barbar’

    Пример, конечно, сильно упрощенный, но принцип тот же.


    Сейчас всё работает как нужно. Простите, пожалуйста, за неудобства и, если вас затронула такая проблема, обратитесь к нам через форму обратной связи.


    Мы ищем возможность вернуть комментарии их законным владельцам, расскажем, что из этого получилось позже.

    ТechMedia
    1129,00
    Создаем и развиваем сервисы для гиков
    Поддержать автора
    Поделиться публикацией

    Похожие публикации

    Комментарии 24

      0
      Т.е., кто то мог опубликовать плохой комментарий от чужого профиля? Или от своего профиля но с чужим именем?
        0

        Или вообще оставить комментарий в другой статье.

          +2
          Кто-то мог опубликовать плохой комментарий и отправить его. Сначала бы он увидел свой никнейм, но после перезагрузки страницы, никнейм бы поменялся на другого пользователя.

          Как у же писал мой коллега, к счастью, у нас всего 15 таких комментариев. Мы работаем с ними.
          +1
          По нашим данным, за выходные с мобильной версии было отправлено 774 комментария. Каждый из них мог пострадать.

          Уточнили, что пострадавших комментариев всего 15 штук.
            0
            В мобильной версии у некоторых скрытых/удалённых постов можно смотреть комментарии.

            Примеров, к сожалению, указать не могу, сейчас пытался открыть несколько таких статей, но не воспроизвелось, однако замечал это несколько раз, поэтому не думаю, что показалось.

            Возможно, было исправлено при исправлении описанного в данном посте.
              0
              В мобильной версии (андроид) частенько невозможно голосовать за статью. Кнопок-стрелок просто нет.
                0
                Так же в мобильной версии невозможно пройти опрос — просто ошибка при попытке открытия опроса.
                Это продолжается уже более, чем пол-года.
                  +1
                  Поясните, пожалуйста, причем здесь VueJS?
                    +2
                    Напрямую ни при чем. Но VueJS часто используется в связке с SSR (на nuxt или express), и вот тут-то это проблема вполне актуальна.
                    +2
                    В мобильной версии часто бывает, что практически невозможно переключиться на просмотр комментариев. Особенно когда их больше большое количество.
                      +1
                      Да, к сожалению такое наблюдаем, особенно в метро. Мы работаем над оптимизацией комментариев, но сроков дать не могу.
                      +4
                      Уж сколько лет прошло, а программисты продолжают наступать на грабли глобальных переменных. Эх.
                        0
                        Самому стыдно… Но я поставил себя в угол, подумал и больше такого не допустим.
                        0
                        Я правильно понимаю, что вы добавляете комментарий командой «get»?
                          0
                          (это пример кода)
                            0
                            немного перефразируя, «в примере есть только доля примера»
                            Но это ведь был вопрос, а не утверждение.
                              +1
                              Мы привели самый простой пример кода. К настоящему коду он отношения не имеет, но баг повторяет (:
                          0
                          В мобильной версии нельзя отправить комментарий, если кармы недостаточно.
                          В некоторых постах в мобильной версии не работают гифки, например тут
                          ссылка на гифку в мобильной версии и с полной версии.
                            0
                            В мобильной версии нельзя отправить комментарий, если кармы недостаточно.

                            Посмотрим, спасибо!
                            В некоторых постах в мобильной версии не работают гифки

                            Чтобы не взрывать телефоны людей, мы сжимаем на сервере картинки и отдаем разные размеры, в зависимости от экрана пользователя. По тапу на картинку, откроется ее оригинал, в котором будет работать анимация.
                              +5
                              Так напишите на превью водяным знаком «gif» :)
                                0
                                Спасибо за идею. daleraliyorov возьми на карандаш, пожалуйста.
                            +1
                            Я конечно все понимаю, но кто глобальные переменные использует в коде? Я и сам на экспрессе работаю и никогда не было такого момента, что без них не обойтись.

                            Ясное дело, что глобальная будет меняться каждый раз при ее изменении. Но все дело в том, что у вас есть объект req. Ничто не мешает его изменять, добавлять доп поля и тд. Таким образом у вас всегда для каждого запроса будут свои переменные, которые не будут переопределяться. Даже если 100500 пользователей одновременно бросят запрос на этот маршрут
                              +1

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

                              +2
                              Забавная ошибка. Очень круто что решили о ней прямо сообщить. Удачи с усмирением сбежавших комментариев :)

                              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                              Самое читаемое