Хроники одного обновления.
16 января 2014, 15:57 | Поговорим о сайте Автор: Night_Ghost
В компьютерном мире, как впрочем и в мире реальном, новое не всегда значит хорошее - и при последнем обновлении движка сайта это удалось полностью прочувствовать. А началось все с нахождения одной интересной идеи - дать возможность увидеть, что другие участники заносят в "Избранное". Но попытка сделать это "в лоб" натолкнулась на огромный объем требуемых переделок. Немного напрягаем Гугль - и обнаруживаем, что оказывается необходимое АПИ уже есть в более свежей версии BuddyPress - 1.9.
Однако мы ранее отказались от бинарной совместимости - слишком большим стал объем различий между движком и оригиналом, и уже практически не накладываются ни патчи "наши изменения", ни тем более "их изменения". К тому же направление развития, избранное авторами BuddyPress, представляется слегка вредительским, а их отношение к совместимости вообще не описывается цензурными словами: в версии 1.8 перестали работать все (!) плагины... как и при переходе с версии 1.2 на 1.5. Вторая причина - так называемая "совместимость тем", АПИ для отображения всех элементов интерфейса BuddyPress в непредназначенных для того темах - вариантах оформления сайта. Ну да, для вновь создаваемого сайта это весомый плюс - но вот если давно есть своя отлаженная тема, то эта (неотключаемая!) "совместимость" становится источником кучи проблем: надо еще определить, когда какое будет использовано оформление, наше или встроенное. И где искать тот кусок кода, который его выводит? Все-таки темы были придуманы совсем не зря, позволяя отделить внешний вид от функциональности - а тут явно обратное направление развития...
Поэтому решаем запастись терпением, и вливать патчи апдейта руками. Благо нужны далеко не все, ибо бОльшая часть из них продолжает вредительскую линию "красивого кода", когда ради академической правильности в жертву приносится скорость работы и удобство отладки. Ну да, может глобальные переменные это зло - но одна переменная с хорошо документированным классом это явно меньшее зло, чем ~900 вызовов функции, возвращающей этот же класс - при формировании одной страницы!
Два дня работы - и отладочный сервер благополучно отображает сайт на новой версии. Правда работает пока далеко не все - в том числе не работают карты участников. Это не удивительно: изменения были совсем не косметические - помимо того, что всех объектах добавилась возможность подключения метаданных к запросам (ради чего все и было затеяно), еще принципиально изменился способ отбора участников.
Раньше каждый компонент сам занимался отбором своих участников - но это ведь концептуально неправильно! Вот в Wordpress'е и появился класс UserQuery, производящий унифицированный поиск и отбор - и вроде как BuddyPress начная с версии 1.8 перешел именно на его использование, расширив производным классом BP_UserQuery для отбора вообще, а его - расширив классом BP_UserGroupQuery для отбора участников группы. При этом естественно старые отборы остались не у дел, вместе со всеми нашими изменениями и всеми фильтрами. Но идея такого отбора представляется более правильной - единая точка обработки одного объекта - поэтому решаем заставить все это работать.
Так что еще пара дней уходит на то, чтобы переделать отборы участников по картам на новый лад. Вот наконец начерно все заработало, а значит пришло время нагрузочного теста. Его задача - проверить, как все будет работать если участников будет миллион, соответственно больше групп, событий и так далее. Если все сделано правильно, то заметного падения скорости происходить не должно.
Но не в этот раз! На такой огромной базе все запросы стали выдавать что участников нет вообще! Начинаем разбираться, и от обнаруженного волосы становятся дыбом от ужаса: для отбора на страницу 20-и участников, вместо того чтобы формировать единый SQL-запрос, класс BP_UserQuery сначала выбирает номера ВСЕХ участников группы, потом их передает в запрос по свойствам участников, а потом этот список номеров передается в класс UserQuery для отбора из них очередной 20-ки. И что самое забавное, судя по комментариям вокруг этого безобразия, это сделано ради... оптимизации запросов и исключения JOIN-ов!
А теперь немного цифр. В списке из миллиона номер это 6 цифр, вместе с разделителем это будет 7 байт - то есть весь список занимает 7 мегабайт! Более того, он в запрос передается дважды - для отбора и для сортировки, а значит размер такого запроса составляет 14мб!!! А максимальный размер пакета данных SQL-сервера по умолчанию - всего 4 мегабайта, вот он и не влезает, так что вместо данных возвращается ошибка.
Можно конечно и настройки сервера поменять - вот только время передачи и обработки такого запроса составляет секунды, так что этот способ был тоже признан вредительским. И что - откатывать все изменения? А ведь идея одного универсального отбора таки правильная... Значит - пишем свои классы! "По образу и подобию" - чтобы снаружи они выглядели как родные, а внутри работали правильно, не составляя чудовищные списки - а уточняя и расширяя SQL-запрос.
Как говорится в сказках, долго ли коротко ли, но вот классы написаны и начерно работают. При этом время выполнения "страшных" JOIN-ов на нагрузочной базе оказалось даже меньше времени выполнения чудовищно длинных "оптимизированных" запросов А пока мы боролись с "оптимизациями", обновился и WordPress. В анонсе новой версии - красивые слова про "самый красивый апдейт", "современную эстетику" и прочие вкусности. Все равно ж обновляем - значит обновим и его! Смутило только изобилие фотографий мобильных устройств в анонсе, ну да ладно...
Быстренько делается патчсет, включающий изменения между старой и новой "ванильными" версиями, и накатывается на сайт. Первый просмотр - все работает, ничего не поменялось. И это правильно Ведь сам Wordpress тут скрыт в глубине, проявляясь только в админке. Так что пришло время отладки.
...и поперли баги. Толпами. Колоннами и шеренгами. Отвалилась произвольная сортировка блогов, лента активности стала вести себя черте как, перестали работать таксономии по объектам, участники даже без админских прав получили доступ к чужому медиаконтенту, медиафайлы перестали преобразовываться в проигрыватели, и прочая прочая. И ладно бы из-за наших кривых правок - в специальной, "ванильной" версии движка большинство багов было на месте!
И в довершение всего, обещанный "красивый апдейт" обернулся вырвиглазными цветами, черно-белыми грубыми иконками в редакторе и расползанием многих диалогов... И если заточенную под мобильники "красоту" можно было просто откатить назад, то битва с багами продолжалась две с лишним недели. И вот "после тяжелой, продолжительной..." отладки результат был представлен на публику. Вместе с парой незамеченых багов, кои были отловлены и прибиты парой дней позже.
После такого апдейта невольно задаешь себе вопрос - а зачем оно было надо? Весь видимый результат - новые циферки в номерах версий да чуть более унифицированные отборы. А ведь за время, потраченное сначала на обновление, а затем на борьбу с ним, можно было сделать много более востребованных вещей, благо список планируемых доработок занимает 8 страниц и уменьшаться похоже не собирается...
"Чтобы сделать человеку ХОРОШО, нужно сначала Всё испортить (сделать плохо), а потом всё вернуть КАК БЫЛО"
Угу, классический метод "заведи козла". Вот только козла мы выгнали, а запах остался...