Легко заметить, что данный компонент не столь совершенен, как мог бы. Скажем, напрашивается вопрос: а нельзя ли в «Ленте друзей» учитывать структуру связей пользователя с группами и другими пользователями социальной сети? Можно — в теории. На практике нагрузка на сервер возрастет в разы (если не на порядки), причем, кэшировать что-либо будет невозможно. Причина заключается в необходимости учитывать огромное количество комбинаций настроек, слишком много факторов будут определять итоговый результат.
Судите сами. Посмотрим, как будет влиять на содержимое "Ленты друзей" сложная конфигурация прав доступа. Допустим, в профиле пользователя имеются настройки:
Настройки доступа к блогам пользователя:
Настройки приватности группы:
Настройки доступа к блогам группы:
Все это придется проверять для каждого (!) блога, который, так или иначе, будет попадать в чью-либо ленту. Наглядный пример. Допустим, Иван состоит в группе «Любители виски», которая видима всем посетителям сайта, но сообщения блогов могут читать только члены группы, и свой блог Иван разрешает читать только своим друзьям. Петя состоит в группе «Любителей молока», которая видима всем посетителям сайта, и сообщения блогов открыты для всех. Петя — друг Ивана и читать сообщения из своего блога тоже разрешает только друзьям. Маша не состоит в указанных группах, и сообщения из своего блога разрешает читать всем посетителям сайта. При этом, Маша — друг Пети.
Теперь, если Петя захочет почитать ленту Ивана, то ему должны быть доступны только сообщения из блога Ивана. Если же Иван будет читать ленту Пети, то он должен видеть сообщения из блога Пети и из блога группы «Любителей молока». Маша, посетив ленту Ивана, вообще не должна видеть сообщений, а в ленте Пети – видеть только сообщения из группы «Любителей молока». Если Иван или Маша посетят ленту группы «Любителей молока», то они должны видеть сообщения из блога группы и сообщения из блога Пети. В ленте Маши, Вася и Петя должны будут видеть только сообщения из блога Маши.
Таким образом, для каждого посетителя каждой ленты придется генерировать уникальный кэш, что совершенно противопоказано для метода «полного кэширования результата» (когда сохраняется полностью готовый результат и на время жизни кэша он выдается без единого запроса к базе данных и вычислений в рамках логики компонента). Если предположить, что каждая лента будет состоять, скажем, из 10 страниц, а всего активных участников социальной сети (без учета групп!) составляет, например, 1000, то только для лент пользователей будет генерироваться 10 страниц ленты * 1000 лент * 1000 пользователей = 10 000 000 кэш-файлов. Если каждый кэш-файл будет занимать порядка 30 000 байт дискового пространства, то суммарный объем кэш-файлов только лент будет составлять 10 000 000 * 30 000 = 300 000 000 000 байт или около 279 гигабайт! Мягко говоря, немало.
Как вариант, можно было бы использовать метод генерации страниц ленты с частичным, но не значимым кэшированием. Но полумеры не спасают. Нагрузка на сервер возрастает, несущественно снижая объем кэша (в экспериментах – примерно в три раза) и радикально усложняя логику обработки (как минимум придется тщательно заботиться о сбросе некорректного кэша), отладку и сопровождение модуля.
В итоге, при создании социальной сети для сайта pcmag.ru, было принято решение реализовать ленту примерно в том виде, как описано в данной статье (ряд мелких деталей опущен для удобочитаемости кода и текста). Да и, как показывает практика, особенной надобности в подключении к «Ленте друзей» дополнительных сущностей, в общем-то, не возникает. При необходимости (например, если все пользователи вдруг дружно возжелали видеть фотографии друг друга) компонент может быть доработан и расширен.