Sway Solstice — различия между версиями
(Новая: Sway Solstice - название Новой Платформы для веб-приложений, выросшей из Vitaphoto. == Цель == Цель — добиться: ...) |
|||
Строка 1: | Строка 1: | ||
− | Sway | + | Sway Solstice — название Новой Платформы для веб-приложений, выросшей из [[Vitaphoto]]. |
== Цель == | == Цель == | ||
Строка 15: | Строка 15: | ||
* Модули, модули, модули, и ничего, кроме модулей. Никаких жёстких завязок на соединение с БД или разбор URL в самом Sway. | * Модули, модули, модули, и ничего, кроме модулей. Никаких жёстких завязок на соединение с БД или разбор URL в самом Sway. | ||
* Конфигурация приложения представляет собой вложенный хеш, хранимый просто в виде Perl-кода. Система загрузки конфигурации позволяет объединять несколько файлов для поддержки стандартных конфигураций. | * Конфигурация приложения представляет собой вложенный хеш, хранимый просто в виде Perl-кода. Система загрузки конфигурации позволяет объединять несколько файлов для поддержки стандартных конфигураций. | ||
− | * Каждый модуль в рамках одного веб-приложения создаётся в одном экземпляре. Модули создаются по | + | * Каждый модуль в рамках одного веб-приложения создаётся в одном экземпляре. Модули создаются по требованию — при первом обращении. Межмодульное взаимодействие тривиально — <code>$www->name</code> через AUTOLOAD даёт экземпляр модуля name. Если модуль name захочет, он даже сможет переопределить то, что возвращается AUTOLOAD с его именем — это удобно для модулей, в которых только 1 функция. |
− | * Использование [[Filter::AutoImport]], чтобы не писать в начале каждой функции длинные серии объявлений переменных <code>$self->www->config</code> | + | * Использование [[Filter::AutoImport]], чтобы не писать в начале каждой функции длинные серии объявлений переменных <code>$self->www->config</code> и т. п. |
− | * Нет никаких RenderRec (в прошлой версии | + | * Нет никаких RenderRec (в прошлой версии «запрос»), и уж конечно он не является точкой сбора огромного числа функциональности. |
− | * Нет виртхостов, нет пресловутого | + | * Нет виртхостов, нет пресловутого «config=?» — идея нескольких виртхостов в одной базе себя не оправдала. |
* Нет завязки на вызов метода render() у модулей, то есть методы обработки можно создавать любые по желанию. | * Нет завязки на вызов метода render() у модулей, то есть методы обработки можно создавать любые по желанию. | ||
− | * Нет жёстких завязок на последовательности выполнения (например сначала этот модуль, потом этот, потом тот), а есть функции | + | * Нет жёстких завязок на последовательности выполнения (например сначала этот модуль, потом этот, потом тот), а есть функции модулей — вызывай, как хочешь. |
− | * Нет хеша $t имён таблиц, сопоставляющего «реальные» таблицы «виртуальным», задуманного на случай сожительства двух приложений в одной БД ($config->{t}) | + | * Нет хеша $t имён таблиц, сопоставляющего «реальные» таблицы «виртуальным», задуманного на случай сожительства двух приложений в одной БД ($config->{t}) — идея ущербная. |
* Нет завязки на регулярные выражения в разборе URI, а точнее, нет вообще никакой завязки в разборе URI, как и самого стандартного разбора URI, кроме «страница?параметры». | * Нет завязки на регулярные выражения в разборе URI, а точнее, нет вообще никакой завязки в разборе URI, как и самого стандартного разбора URI, кроме «страница?параметры». | ||
* Обёрнутые в функции обращения к БД из модулей. Живут они в Sway::db::, а рядом с ними лежат SQL дампы нужных таблиц. | * Обёрнутые в функции обращения к БД из модулей. Живут они в Sway::db::, а рядом с ними лежат SQL дампы нужных таблиц. | ||
− | * Новая версия [[Шаблонизатор VMX::Template|Шаблонизатора VMX::Template]] | + | * Новая версия [[Шаблонизатор VMX::Template|Шаблонизатора VMX::Template]] — упрощённая, аккуратная, почищенная, ещё более быстрая. |
− | *: Шаблонизатор специально сделан максимально простым, дабы избежать анти-паттернов разработки, к которым подталкивает {{CPAN|Template::Toolkit}}, а именно, к перемещению | + | *: Шаблонизатор специально сделан максимально простым, дабы избежать анти-паттернов разработки, к которым подталкивает {{CPAN|Template::Toolkit}}, а именно, к перемещению 50 % логики приложения в шаблоны. Примеры того, где так происходит — [http://www.bugzilla.org/ Bugzilla], [http://www.vsem.ru/ Vsem.ru]. |
*: [[VMX-Template]] создан когда-то по мотивам шаблонизатора phpBB2, самого созданного по мотивам шаблонизатора [http://sourceforge.net/projects/phplib/ phplib], о чём напоминает его синтаксис. Умеет он буквально 5 вещей: циклы, IF’ы, INCLUDE (включение другого шаблона), подстановки выражений в код, присваивания. Данные в шаблон передаются просто Perl-хешем, без промежуточных уровней вроде <code>assign_vars()</code> и <code>assign_block_vars()</code> (phpBB2), {{CPAN|Template::Stash}} (TT). Код шаблонакомпилируется сначала в Perl-код и кэшируется на диске, а потом компилируется интерпретатором и кэшируется в памяти. | *: [[VMX-Template]] создан когда-то по мотивам шаблонизатора phpBB2, самого созданного по мотивам шаблонизатора [http://sourceforge.net/projects/phplib/ phplib], о чём напоминает его синтаксис. Умеет он буквально 5 вещей: циклы, IF’ы, INCLUDE (включение другого шаблона), подстановки выражений в код, присваивания. Данные в шаблон передаются просто Perl-хешем, без промежуточных уровней вроде <code>assign_vars()</code> и <code>assign_block_vars()</code> (phpBB2), {{CPAN|Template::Stash}} (TT). Код шаблонакомпилируется сначала в Perl-код и кэшируется на диске, а потом компилируется интерпретатором и кэшируется в памяти. | ||
* Поддержка [[Funq]]. Штука получилась интересная, хотя и не факт, что распространится. | * Поддержка [[Funq]]. Штука получилась интересная, хотя и не факт, что распространится. | ||
Строка 31: | Строка 31: | ||
Примеры: | Примеры: | ||
− | * Диспетчер URI, сопоставляющий ссылки | + | * Диспетчер URI, сопоставляющий ссылки страницам — отдельный модуль, который, увы, пишется отдельно, хотя есть стандартные. |
− | * БД и | + | * БД и кэш — тоже отдельные модули. Хочешь — используй, хочешь — нет. Хочешь — пиши свои. |
− | * Например каждый метод | + | * Например каждый метод авторизации — функция модуля auth. |
* Например, нет функции вывода в шаблон треда комментариев, а есть функция, возвращающая его в виде хеша, передавай в шаблон, как хочешь. | * Например, нет функции вывода в шаблон треда комментариев, а есть функция, возвращающая его в виде хеша, передавай в шаблон, как хочешь. | ||
Строка 91: | Строка 91: | ||
* Скрытые форумы, привязка сообщений к разделам сайта; | * Скрытые форумы, привязка сообщений к разделам сайта; | ||
− | А | + | А лучше — никакая, а просто взять готовый форумный движок. |
=== Как быть с генерацией и разбором URI? === | === Как быть с генерацией и разбором URI? === | ||
Строка 97: | Строка 97: | ||
Общая идеология веб-приложения, на самом деле, весьма нетривиальная штука. | Общая идеология веб-приложения, на самом деле, весьма нетривиальная штука. | ||
− | Должна присутствовать возможность реализации различных диспетчеров URI, | + | Должна присутствовать возможность реализации различных диспетчеров URI, то есть разных методов разбора. Например, наиболее простой — /компонент/?key=value&key=value. Другой пример — когда у каждого документа есть фиксированный URI, вообще никак не связанный с его ID и т. п., а связанный только с названием и моментом создания, «как завещал великий W3C». |
А разные методы разбора провоцируют разные методы генерации. | А разные методы разбора провоцируют разные методы генерации. | ||
− | А кроме того, не хочется иметь | + | А кроме того, не хочется иметь «единых» функций диспетчеризации, то есть не хочется, чтобы всё нужно было прописывать явно в одно место. |
− | А кроме того, все модули создаются по требованию, поэтому | + | А кроме того, все модули создаются по требованию, поэтому «заранее» выставлять настройки своих стандартных URI не могут. |
На входе мы имеем некоторый **адрес страницы**, то есть практически набор неких параметров. | На входе мы имеем некоторый **адрес страницы**, то есть практически набор неких параметров. | ||
Строка 109: | Строка 109: | ||
На выходе мы имеем саму страницу. В рамках нашей идеологии она составляется из готовых блоков, предоставляемых компонентами. | На выходе мы имеем саму страницу. В рамках нашей идеологии она составляется из готовых блоков, предоставляемых компонентами. | ||
− | ''Проблемы'' начинаются, когда мы хотим сослаться из компонента на какую-то другую | + | ''Проблемы'' начинаются, когда мы хотим сослаться из компонента на какую-то другую страницу… Простейший пример: к стандартному компоненту — отображалке списка тем форума — прицепляется сбоку какой-то переключатель. Получается что у списка тем есть контекст — как минимум номер текущей страницы, и у переключателя есть свой контекст! Переключатель должен как-то сослаться на текущую страницу, в которой изменён его контекст. КАК??? |
− | Фактически должно существовать некое | + | Фактически должно существовать некое «обратное преобразование» для каждого компонента, позволяющее компоненту получить тот адрес, по которому появится нужная функциональность. КАК??? |
Можно просто забить и отдать URI на откуп шаблонам. Но что, если в дальнейшем понадобится изменить общую схему их генерации? Проблема. | Можно просто забить и отдать URI на откуп шаблонам. Но что, если в дальнейшем понадобится изменить общую схему их генерации? Проблема. | ||
− | Можно делать как и | + | Можно делать как и раньше — дёргать из кода функцию uri(«ТИП», {параметры}). Но что, если в дальнейшем понадобится использовать разные типы в вызовах одного компонента? Тоже проблема. |
− | Однако ближе к | + | Однако ближе к «телу» лежит всё-таки идея генерации URI из шаблонов, так как именно шаблоны действительно ЗНАЮТ, какой тип страницы собой представляют. |
'''Посему вывод: генерацию URI оставляем в шаблонах, но через специальную функцию, которая может осуществлять маппинг URI.''' | '''Посему вывод: генерацию URI оставляем в шаблонах, но через специальную функцию, которая может осуществлять маппинг URI.''' | ||
− | Но тут возникает новая проблема! Что делать с различными редиректами из кода? Ссылки нужны, а шаблонов-то | + | Но тут возникает новая проблема! Что делать с различными редиректами из кода? Ссылки нужны, а шаблонов-то нет — ЧТО ДЕЛАТЬ??? |
− | С редиректами из кода ещё можно | + | С редиректами из кода ещё можно побороться — от них можно отказаться :) оставив только для специальных случаев, вроде редиректов на безопасные УРЛы и т. п. То есть в случае «чего» компонент чтобы не редирект давал, а некие данные в хеше результата возвращал. Это, в целом, даже идеологически неплохо. |
− | И ещё один | + | И ещё один кейс — это к примеру JSON-ответы: «нормальных» шаблонов нет, URI нужны. ЧТО ДЕЛАТЬ??? Можно конечно на этот случай как раз оставить дёрганье фиксированного uri(ЧЕГО_ТО). |
− | + | === Как быть с хешем переименований таблиц $t ? === | |
− | Вероятно, его нужно ликвидировать, | + | Вероятно, его нужно ликвидировать, так как в большинстве случаев он бессмыслен… |
− | С другой стороны, а если произойдёт та ситуация, ради которой он | + | С другой стороны, а если произойдёт та ситуация, ради которой он задуман — допустим будем ставиться в одну базу с чем-нибудь другим и будут конфликты имён таблиц? |
Может быть, использовать Funq? | Может быть, использовать Funq? | ||
Строка 137: | Строка 137: | ||
Кстати, для полной абстракции от БД нужно все вызовы SQL оборачивать в функции. | Кстати, для полной абстракции от БД нужно все вызовы SQL оборачивать в функции. | ||
− | **Вывод: хеш $t ликвидировать в задницу, в библиотечных модулях все вызовы к БД оборачивать в функции** | + | ** Вывод: хеш $t ликвидировать в задницу, в библиотечных модулях все вызовы к БД оборачивать в функции** |
[[Категория:Разработка]] | [[Категория:Разработка]] | ||
[[Категория:Sway]] | [[Категория:Sway]] |
Версия 16:36, 23 августа 2009
Sway Solstice — название Новой Платформы для веб-приложений, выросшей из Vitaphoto.
Содержание
Цель
Цель — добиться:
- Модульности.
- Возможности повторного использования кода.
- Простоты и гибкости в использовании.
Идеи
Реализованные:
- Модули, модули, модули, и ничего, кроме модулей. Никаких жёстких завязок на соединение с БД или разбор URL в самом Sway.
- Конфигурация приложения представляет собой вложенный хеш, хранимый просто в виде Perl-кода. Система загрузки конфигурации позволяет объединять несколько файлов для поддержки стандартных конфигураций.
- Каждый модуль в рамках одного веб-приложения создаётся в одном экземпляре. Модули создаются по требованию — при первом обращении. Межмодульное взаимодействие тривиально —
$www->name
через AUTOLOAD даёт экземпляр модуля name. Если модуль name захочет, он даже сможет переопределить то, что возвращается AUTOLOAD с его именем — это удобно для модулей, в которых только 1 функция. - Использование AutoImport, чтобы не писать в начале каждой функции длинные серии объявлений переменных
$self->www->config
и т. п. - Нет никаких RenderRec (в прошлой версии «запрос»), и уж конечно он не является точкой сбора огромного числа функциональности.
- Нет виртхостов, нет пресловутого «config=?» — идея нескольких виртхостов в одной базе себя не оправдала.
- Нет завязки на вызов метода render() у модулей, то есть методы обработки можно создавать любые по желанию.
- Нет жёстких завязок на последовательности выполнения (например сначала этот модуль, потом этот, потом тот), а есть функции модулей — вызывай, как хочешь.
- Нет хеша $t имён таблиц, сопоставляющего «реальные» таблицы «виртуальным», задуманного на случай сожительства двух приложений в одной БД ($config->{t}) — идея ущербная.
- Нет завязки на регулярные выражения в разборе URI, а точнее, нет вообще никакой завязки в разборе URI, как и самого стандартного разбора URI, кроме «страница?параметры».
- Обёрнутые в функции обращения к БД из модулей. Живут они в Sway::db::, а рядом с ними лежат SQL дампы нужных таблиц.
- Новая версия Template|Шаблонизатора VMX::Template“Template|Шаблонизатора VMX::Template” не может быть использован как заголовок статьи на данном сайте.— упрощённая, аккуратная, почищенная, ещё более быстрая.
- Шаблонизатор специально сделан максимально простым, дабы избежать анти-паттернов разработки, к которым подталкивает Template::Toolkit, а именно, к перемещению 50 % логики приложения в шаблоны. Примеры того, где так происходит — Bugzilla, Vsem.ru.
- VMX-Template создан когда-то по мотивам шаблонизатора phpBB2, самого созданного по мотивам шаблонизатора phplib, о чём напоминает его синтаксис. Умеет он буквально 5 вещей: циклы, IF’ы, INCLUDE (включение другого шаблона), подстановки выражений в код, присваивания. Данные в шаблон передаются просто Perl-хешем, без промежуточных уровней вроде
assign_vars()
иassign_block_vars()
(phpBB2), Template::Stash (TT). Код шаблонакомпилируется сначала в Perl-код и кэшируется на диске, а потом компилируется интерпретатором и кэшируется в памяти.
- Поддержка Funq. Штука получилась интересная, хотя и не факт, что распространится.
Примеры:
- Диспетчер URI, сопоставляющий ссылки страницам — отдельный модуль, который, увы, пишется отдельно, хотя есть стандартные.
- БД и кэш — тоже отдельные модули. Хочешь — используй, хочешь — нет. Хочешь — пиши свои.
- Например каждый метод авторизации — функция модуля auth.
- Например, нет функции вывода в шаблон треда комментариев, а есть функция, возвращающая его в виде хеша, передавай в шаблон, как хочешь.
Планируемые:
- Версионирование схем баз данных с возможность генерации скрипта проноса или отмены обновлений.
Обработчик приложения делает фактически только eval {} для отлова исключений и подключение директорий @INC. В старой платформе обработчик делал Много Чего, в результате появлялись жёсткие завязки на различные моменты. Теперь же платформа от них свободна, и вся функциональность, имевшая жёсткие завязки, теперь разнесена по модулям, и её можно как использовать, так и не использовать:
Стандартные библиотечные модули больше не предоставляют собой «готовых страниц» — каждый модуль теперь являет собой просто библиотеку функций, а функции, выводившие что-то в шаблон, теперь просто возвращают хеш, который можно подставлять, куда душе угодно.
Страница в ответе формируется теперь не из конкатенации вывода нескольких шаблонов (что, кстати, влекло довольно кривой обходной манёвр в шаблонизаторе для организации передачи значений из шаблона в шаблон), а из вывода одного шаблона, который, возможно, пожелает включить в себя какие-либо другие.
Некоторые раздумья
Вопросы, возникавшие в процессе разработки.
Установка обработчика в Apache
Требования:
- Должна обеспечиваться возможность работы нескольких экземпляров одного приложения в одном экземпляре веб-сервера и одном интерпретаторе (без PerlOptions +Parent);
- Установка обработчика должна быть максимальной простой, без извращений с вызовом Perl кода Sway::WWW->Apache2(..);
- Должно быть возможно чтобы пакеты-обработчики были разные, а не один на _все_ приложения. То есть чтобы приложение могло сделать свой обработчик.
Решение:
PerlFlags -I/home/www/vitaphoto/lib # задаётся путь к библиотекам PerlSetVar SwayConfig /etc/sway/vitaphoto.conf # задаётся конфигурационный файл PerlResponseHandler Sway::WWW # и обработчик
А Sway::WWW уже передаст запрос в нужный экземпляр приложения, который не обязательно будет экземпляром класса Sway::WWW.
Модули и компоненты?
Нужно ли идеологически разделять модули на модули и компоненты ? (первое — просто предоставляют какие-то функции, второе — представляют собой конкретную страницу).
- За: Меньше помойка.
- Против: Компонент одновременно может быть и модулем.
- За: Компонент типа attach из старой версии Sway представляет собой некоторую //конкретную// функциональность.
- Против: С другой стороны, почему бы не представить эту функциональность в виде функции вывода чего-то в шаблон?
- За: Вероятно, нужно будет писать меньше кода в случае использования готового компонента.
- Против: Как быть с изменением организации страницы? Например, с добавлением других шаблонов?
Последний пункт является решающим. В рамках выбранной идеологии «готовых компонентов» существовать просто не может.
Форумная функциональность?
Какая функциональность в форумном движке является необходимой? По убывания необходимости:
- Форумы, темы, сообщения, BBкоды;
- Прикреплённые темы, темы с обратным отображением, иерархические темы, темы с автоматическим индексом в верхнем сообщении;
- Email и RSS подписки на новые сообщения, слежение за темами.
- Профили пользователей (icq, телефон, email, настройки, на форуме GTSR — к примеру, машина), личные сообщения.
- Скрытые форумы, привязка сообщений к разделам сайта;
А лучше — никакая, а просто взять готовый форумный движок.
Как быть с генерацией и разбором URI?
Общая идеология веб-приложения, на самом деле, весьма нетривиальная штука.
Должна присутствовать возможность реализации различных диспетчеров URI, то есть разных методов разбора. Например, наиболее простой — /компонент/?key=value&key=value. Другой пример — когда у каждого документа есть фиксированный URI, вообще никак не связанный с его ID и т. п., а связанный только с названием и моментом создания, «как завещал великий W3C».
А разные методы разбора провоцируют разные методы генерации.
А кроме того, не хочется иметь «единых» функций диспетчеризации, то есть не хочется, чтобы всё нужно было прописывать явно в одно место.
А кроме того, все модули создаются по требованию, поэтому «заранее» выставлять настройки своих стандартных URI не могут.
На входе мы имеем некоторый **адрес страницы**, то есть практически набор неких параметров.
На выходе мы имеем саму страницу. В рамках нашей идеологии она составляется из готовых блоков, предоставляемых компонентами.
Проблемы начинаются, когда мы хотим сослаться из компонента на какую-то другую страницу… Простейший пример: к стандартному компоненту — отображалке списка тем форума — прицепляется сбоку какой-то переключатель. Получается что у списка тем есть контекст — как минимум номер текущей страницы, и у переключателя есть свой контекст! Переключатель должен как-то сослаться на текущую страницу, в которой изменён его контекст. КАК???
Фактически должно существовать некое «обратное преобразование» для каждого компонента, позволяющее компоненту получить тот адрес, по которому появится нужная функциональность. КАК???
Можно просто забить и отдать URI на откуп шаблонам. Но что, если в дальнейшем понадобится изменить общую схему их генерации? Проблема.
Можно делать как и раньше — дёргать из кода функцию uri(«ТИП», {параметры}). Но что, если в дальнейшем понадобится использовать разные типы в вызовах одного компонента? Тоже проблема.
Однако ближе к «телу» лежит всё-таки идея генерации URI из шаблонов, так как именно шаблоны действительно ЗНАЮТ, какой тип страницы собой представляют.
Посему вывод: генерацию URI оставляем в шаблонах, но через специальную функцию, которая может осуществлять маппинг URI.
Но тут возникает новая проблема! Что делать с различными редиректами из кода? Ссылки нужны, а шаблонов-то нет — ЧТО ДЕЛАТЬ???
С редиректами из кода ещё можно побороться — от них можно отказаться :) оставив только для специальных случаев, вроде редиректов на безопасные УРЛы и т. п. То есть в случае «чего» компонент чтобы не редирект давал, а некие данные в хеше результата возвращал. Это, в целом, даже идеологически неплохо.
И ещё один кейс — это к примеру JSON-ответы: «нормальных» шаблонов нет, URI нужны. ЧТО ДЕЛАТЬ??? Можно конечно на этот случай как раз оставить дёрганье фиксированного uri(ЧЕГО_ТО).
Как быть с хешем переименований таблиц $t ?
Вероятно, его нужно ликвидировать, так как в большинстве случаев он бессмыслен…
С другой стороны, а если произойдёт та ситуация, ради которой он задуман — допустим будем ставиться в одну базу с чем-нибудь другим и будут конфликты имён таблиц?
Может быть, использовать Funq?
Кстати, для полной абстракции от БД нужно все вызовы SQL оборачивать в функции.
- Вывод: хеш $t ликвидировать в задницу, в библиотечных модулях все вызовы к БД оборачивать в функции**