Pull to refresh

Comments 39

Такое желание есть, но пока фреймворк сыроват и не подготовлен к этому. Поживет еще какое-то время, причешем и, думаю, никаких преград открыть в open source не возникнет.
Мне одному вот эта часть и всё, что дальше напомнило Symfony?
$Request = new Request($_GET, $_POST, $_COOKIE, $_SERVER);
$App = new Application();
$Response = $App->handle($Request);
$Response->send();
UFO just landed and posted this here
И почему здесь нет $_FILES?
Пока что не требовалось, а делать максимально универсально задачи не стояло.
В таких крупных проектах обычно загрузка файлов производится не на вебы, а на специализированные аплоад-сервера. При этом код обработки аплоадов достаточно прост, и, возможно, вообще написан не на php, а, скажем, работает как модуль nginx.
и $_SESSION. А как с ними работа организована?
У нас собственное хранилище для сессий, работа с которым осуществляется через специальный класс, отвечающий за работу с демоном. SessionHandler-ы PHP и массив $_SESSION не используются.
В любом грамотно спроектированном фреймворке эта часть выглядит подобным образом. Тут нет ничего удивительного.
А я еще в 2007-м году предлагал подобное. (Уходит, занудно бубня под нос).
Скажите, а внутри такого большого проекта как ваш потребовалось ли реализовывать механизм вложенного роутинга, т.е. когда контроллер создаёт новый Request, отправляет его в Application, получает ответ и обрабатывает его.

А ещё интересно было бы узнать связываете ли вы как-нибудь пути до action'ов контроллеров с путями внутри шаблонов, или это делается на уровне соглашений и документации?
Ничто не мешает сделать вложенный роутинг, но таких задач не появлялось. Пока столкнулись лишь с ситуацией, когда в маршруте указан Action, результатом работы которого будет другой Action, но с тем же Request-ом. Например, возвращает специальный Action для неавторизованного пользователя.

Шаблоны с action-ами никак не связаны. Контроллер явно создает объект ViewModel, на основе имени которого будет найдет класс View, например ViewModel_Profile -> View_Web_Profile. А дальше в каждом конкретном случае View сама решает откуда брать шаблон, какие пути использовать и т.д.
UFO just landed and posted this here
Я бы не сказал, что Application — это God-object, если я Вас правильно понял, и он не Singleton. Он выполняет четко заданную функцию — исполнить определенный алгоритм обработки HTTP-запроса, основываясь на «чек-поинтах» — событиях.

Исходники, как я уже ответил на первый комментарий, возможно мы откроем в будущем, когда код будет признан стабильным и приведен в «товарный вид».

90% страниц у нас работают как SPA — у нас своя достаточно интересная реализация этого в JS, заточенная под наши нужды, достойная отдельной статьи. Думаю, коллеги из отдела Frontend, в скором времени расскажут про нее.

Я знаю, что системные программисты у нас активно интересуются приложениями на Go, каких-то деталей не могу назвать. HHVM возможно кто-то пробовал, не используем в продакшене.
Просто хочу уточнить, у вас именно SPA или все же Pjax app? Просто если полноценный SPA, тогда причем тут генерация blitz-шаблонов да и вообще понятие «страница»?
Да, скорее Pjax. У нас нет шаблонизации на клиенте, все запрашивается исключительно с сервера. Если переход осуществлен по прямой ссылке, сервер отдаст целиком каркас с блоками без дополнительных запросов. При всех следующих переходах подгружаются лишь блоки (+дополнительные скрипты и стили), а базовый каркас остается.
Да, это базовый pjax сайт. Такие мы делали еще в далеком 2008, как только ajax стал хоть немного варимым. И это прям скажем не интересно, ибо настоящее SPA намного сложнее с точки зрения клиента и намного проще с точки зрения сервера и того как он работает с разнообразными видами клиентов (веб, мобилки, тв итп). Можно сказать что от сервера останутся только «веб-сервисы» в вашей терминологии. Кстати, а ТВ клиенты у вас есть, для Smart TV всяких?
Помимо веба у нас есть лишь мобильные приложения — iOS, Android, Windows, Blackberry, и 2 версии мобильного сайта — HTML5 и версия для более старых мобильных клиентов. Все они работают через единое API. Насколько я знаю, версий для ТВ-клиентов не планируется.
Довольно странно, ведь все крупные соц.сети имеют ТВ клиенты, Badoo всегда казалась мне достаточно крупной. Хотя раз не планируется, значит наверное есть причина…
Ну да, как приятно наверное вечером всей семьей сесть перед телевизором, зайти в баду, и посмотреть кого там муж наснимал.
В процессе работы приложение генерирует события «Получен запрос», «Найден контроллер», «Получены данные», «Поймано исключение», «Рендеринг данных», «Получен ответ».


Вот эта часть один-в-один компонент Symfony HttpKernel. И я не понимаю зачем вы сделали свой велосипед.
Я могу предположить, что HttpKernel зависит от HttpFoundation, который в свою очередь супер кросплатформенный, что вызывает небольшой оверхед
HttpFoundation просто предоставляет удобную ООП-обёртку над разными RFC. Не понимаю как именно он может вызвать оверхед.
Я это всё видел. Тот «оверхед», который вы привели — это просто песчинка в общем времени приложения. И экономия на этих песчинках точно не стоит чтобы велосипедить своё.
Почему не стоит? Если свой вилосипед будет экономить хоть сколько-то на каждом запросе — вполне норм писать свое. Учитывая, что свое можно всегда под себя изменить с легкостью.
Авито недавно рассказывали что под себя драйвер постгреса допилили, ибо он какой-то оверхед делает.

С другой стороны лицензия позволяет форкнуть и допилить, так что вы правы)
Когда у вас 1-2 сервера — песчинка. А когда половина датацентра одних вебов — уже нет ;)
Не согласен, это именно песчинка. Обычно слабое место — это поиск и сортировка данных, а отказываться от удобства и ясности в коде ради пары десятков милисекунд… ну тогда не php надо использовать.
Поиск и сортировка данных делаются в 1% случаев, в 99% случаев происходит чтение из мемкеша.
Мне бы первым делом пришла в голову идея отнаследоваться и оптимизировать такую тяжелую логику под вашу конфигурацию. Много вообще мест в HttpFoundation, которые вам кажутся чрезмерно тяжелыми?
ну, так-то да. Некоторые вещи от туда хорошо бы вынести в расширение на си. Например ParametersBag.
Событийная архитектура — да, тот же очень удобный принцип, но реализация другая. Главное отличие — у нас отрисовка данных (шаблонизация) осуществляется в последний момент. А также сборкой разных блоков занимается сам Application при помощи объектов Layout.
у нас отрисовка данных (шаблонизация) осуществляется в последний момент

Хм, отрисовку данных в HttpKernel можно отложить на самый последний момент с помощью StreamedResponse класса.
А также сборкой разных блоков занимается сам Application при помощи объектов Layout.

Сборка разных блоков — это же шаблонизация. У вас шаблонизацией занимается Application?
И ещё. Наверно «сборка разных блоков» подразумевает вывод в определенное место шаблона контент, который сгенерирован другим контроллером и представлением. В HttpKernel это опять же есть из коробки — Fragment называется.
StreamedResponse в данном случае будет выглядеть костылем, на мой взгляд. У нас есть отдельное событие — RenderEvent. Подписчики получают результат из контроллера и осуществляют шаблонизацию. В данный момент у нас есть два подписчика — первый в объект ParseResult доставляет js_vars, актуальные для большинства страниц, а второй занимается непосредственно шаблонизацией и преобразованием в JSON разных данных. Это достаточно объемная часть, заслуживающая быть выделенной отдельным компонентом.

Layout — это объект, который, во-первых, знает, какие еще контроллеры, помимо главного, надо запустить, принимает результат их работы и знает как его использовать. Это происходит до шаблонизации. Обычно, Layout создает базовый ParseResult_Blitz (который при шаблонизации будет преобразован в HTML при помощи шаблонизатора Blitz). Устанавливает результат работы главного контроллера в блок CENTER, принимает на вход результат работы контроллера сайдбара и устанавливает в SIDEBAR. А сама шаблонизация произойдет позже. То есть под сборкой блоков понимается именно подготовка структуры.

Конечно, можно было бы и на Symfony и на каком-то другом фреймворке сделать подобное, но вопрос в сроках, поддержке и уровне вхождения остается, на мой взгляд, открытым.
Ну всё что вы сейчас описали очень хорошо делается на компонентах симфони. И события у них есть, и результаты работы контроллеров в разные блоки вставлять можно. Видимо у вас просто не было человека с опытом работы в симфони ;)
Я это к чему всё — у меня тоже есть (и продолжается) перевод старого (2007 год) проекта на рельсы симфони. И пока ещё ни разу не довелось жалеть о содеянном :)

А что касается последнего абзаца:
1. Сроки внедрения существующих симфони-компонент, КМК, вполне сопоставимы с разработкой аналогов
2. Поддержка — код симфони-компонент покрыт тестами, + ими пользуются много разработчиков.
3. Уровень вхождения — по симфони есть отличная готовая документация, по внутренним фреймворкам их часто нет :(
Вы правы, специалистов с глубоким знанием Symfony на момент создания фреймворка у нас не было (или кто-то прятался). Изначально мы собрали рабочую группу, которая рассмотрела разные фреймворки, плюсы-минусы, но не могу сказать, что это был очень глубокий обзор.

Рисковать, используя сторонний фреймворк, тоже не хотелось, т.к. нагрузки большие и очень важна скорость. Свое всегда можно достаточно быстро оптимизировать, со сторонними приложениями сложнее. Highload подразумевает зачастую эффективные, но некрасивые решения.
Чужое тоже быстро оптимизируется — форкается и допиливается как надо. + можно отправить пулл реквест и помочь сообществу :)
Оптимизации под высокие нагрузки — это зачастую такие грязные хаки, которые сообществу мало того, что не нужны — их и показывать даже не хочется :) Ну и заметная часть таких оптимизаций — это выпиливание abstraction layers и хардкод под конкретный случай, что сообществу вообще не нужно.
Sign up to leave a comment.