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’

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


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


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

    Habr
    323.61
    Create services for geeks
    Support the author
    Share post

    Comments 26

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

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

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

          Как у же писал мой коллега, к счастью, у нас всего 15 таких комментариев. Мы работаем с ними.
          +3
          По нашим данным, за выходные с мобильной версии было отправлено 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
                              Забавная ошибка. Очень круто что решили о ней прямо сообщить. Удачи с усмирением сбежавших комментариев :)
                                0
                                Говорила бабушка не использовать глобальные переменные…
                                  0
                                  А есть у кого-нибудь еще проблемы с отображением комментариев в мобильном приложении? Они как бы начинают загружаться, а потом закрываются. Иногда они появляются после десятка попыток, а иногда проще найти статью через браузер. Впн выключал, из аккаунта выходил, экран протирал.

                                  Only users with full accounts can post comments. Log in, please.