Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

GNU Mailman

Глава 10 из книги "Архитектура приложений с открытым исходным кодом", том 2.

Оригинал: GNU Mailman
Автор: Barry Warsaw
Перевод: А.Панин

10.2. Список рассылки

Объект списка рассылки (mailing list object), очевидно, является еще одним основным объектом системы Mailman и большинство операций в рамках Mailman осуществляется именно со списком рассылки; эти операции:
  • Участие в списке рассылки начинается после подписки на определенный список рассылки с использованием адреса пользователя.
  • Списки рассылки имеют большое количество настроек конфигурации, хранящихся в базе данных и управляющих всеми аспектами функционирования приложения, начиная с привилегий размещения сообщений и заканчивая способом финальной модификации сообщений перед их доставкой.
  • Списки рассылки имеют владельцев и модераторов, которые обладают большими возможностями по изменению аспектов функционирования списка, а также подтверждения или отклонения спорных сообщений.
  • Каждый список рассылки имеет свой собственный архив.
  • Пользователи отправляют новые сообщения в определенный список рассылки.

и так далее. Практически каждая операция в системе Mailman принимает ссылку на список рассылки в качестве аргумента - это фундаментальная концепция. Объекты списков рассылки были подвергнуты радикальным архитектурным изменениям в версии 3 системы Mailman для повышения их эффективности и гибкости.

Одним из ранних архитектурных решений, принятых John Viega, был способ представления объекта списка рассылки в рамках системы. Для представления этого центрального типа данных он выбрал класс Python с множеством базовых классов, каждый из которых реализовывал небольшую часть функций списка рассылки. Эти работающие совместно базовые классы, называемые смешанными классами (mixin classes), были реализацией разумного способа организации кода, позволяющей просто добавлять необходимые совершенно новые функции. После подключения нового базового смешанного класса основной класс MailList может просто получить возможность выполнения каких-либо новых и замечательных действий.

Например, для добавления автоответчика в версию 2 системы Mailman был создан смешанный класс, который содержал специфические для данной функции данные. Данные должны автоматически инициализироваться при создании нового списка рассылки. Смешанный класс также предоставляет методы, необходимые для поддержки функции автоответчика. Эта структура стала более полезной при проектировании постоянного хранилища объекта списка рассылки MailList.

Другим ранним архитектурным решением, принятым John Viega, является использование модуля pickle языка Python для постоянного хранения данных состояния объекта MailList.

В версии 2 системы Mailman данные состояния объекта MailList сохраняются в файле с именем config.pck, который является простым представлением словаря объекта MailList, сформированным с использованием функций модуля pickle. Каждый объект языка Python имеет соответствующий атрибут в форме словаря с названием __dict__. Таким образом, сохранение объекта списка рассылки заключается в простом преобразовании его словаря __dict__ с использованием функций модуля pickle в файл, а его загрузка - в чтении сохраненных данных из файла и реконструкции словаря __dict__.

Следовательно, когда смешанный класс добавляется для реализации каких-либо новых функций, все атрибуты смешанного класса автоматически преобразуются в файл и реконструируются соответствующим образом. Единственным дополнительным действием, которое нам приходится выполнять, является продержка версии схемы (schema version number) для возможности автоматического обновления устаревших объектов списков рассылок при добавлении новых атрибутов с помощью смешанных классов, так как сохраненное представление устаревших объектов MailList не будет содержать этих новых атрибутов.

Насколько бы не был удобен данный подход, архитектура смешанных объектов и постоянное хранилище данных с использованием функций модуля pickle не выдержали своего собственного веса. Администраторы сайтов часто просили предоставить способы доступа к конфигурационным переменным с использованием внешних систем, не основанных на технологиях языка Python. Но протокол представления данных модулем pickle является в полной мере специфичным для языка Python, поэтому объединение всех важных данных в файлах рассматриваемого формата в данном случае не является разумным. Также, ввиду того, что все данные состояния списка рассылки сохранялись в файле config.pck и система Mailman использовала множество процессов, которые должны были читать, модифицировать и записывать данные состояния списка рассылки, нам пришлось реализовать взаимные, работающие с NFS блокировки на основе файлов для того, чтобы быть уверенными в сохранности данных. В любой момент, когда какой-либо процесс системы Mailman хочет изменить данные состояния списка рассылки, он должен установить блокировку, записать измененные данные, после чего снять блокировку. Даже операции чтения могут потребовать перезагрузки соответствующего списку рассылки файла config.pck, так как некоторый другой процесс может изменить данные до выполнения операции чтения. Эта последовательность операций над данными списка рассылки была ужасно медленной и неэффективной.

По этим причинам система Mailman версии 3 хранит все данные в базе данных SQL. По умолчанию используется база данных SQLite 3, хотя эта настройка может быть просто изменена, так как в версии 3 системы Mailman применяется технология объектно-реляционного отображения (Object Relational Mapper) с названием Strom, поддерживающая большое количество баз данных. Поддержка PostgreSQL была добавлена всего лишь с помощью нескольких строк кода и администратор сайта может включить ее просто изменив одну из переменных конфигурации.

Другой, большей проблемой, присущей версии 2 системы Mailman, является разделенность списков рассылки. Обычно операции администрирования затрагивают множество списков рассылки, а иногда и все. Например, пользователь может захотеть временно заблокировать все свои подписки во время отпуска. Или администратор сайта может захотеть добавить какое-либо предупреждение в сообщение приветствия для всех списков рассылки своей системы. Даже простая операция по установлению того, на какой список подписан пользователь с заданным адресом, требует восстановления данных состояния каждого списка рассылки системы, так как информация о подписчиках также хранится в файле с именем config.pck.

Другая проблема заключалась в том, что каждый файл config.pck хранился в директории с именем, соответствующем названию списка рассылки, но приложение Mailman изначально проектировалось без учета возможности использования виртуальных доменов. Это обстоятельство привело к очень неприятной ситуации, в которой два списка рассылки не могли иметь одно и то же название в различных доменах. Например, если вы владеете и доменом example.com, и доменом example.org и при этом хотите, чтобы они были независимы и использовали отдельные списки рассылки с названиями support, вы не сможете реализовать эту идею в случае использования версии 2 системы Mailman без модификаций кода, использования не поддерживаемой точки вызова функций или определенных мер для обхода ограничения, которые позволяют принудительно устанавливать отличное название списка рассылки незаметно для пользователей и широко используются такими популярными сайтами, как SourceForge.

Эта проблема была решена в версии 3 системы Mailman путем изменения способа идентификации списков рассылки наряду с переносом всех данных в традиционную базу данных. Первичный ключ (primary key) таблицы списка рассылки является полностью определенным именем списка рассылки (fully qualified list name) или, как вы вероятнее воспримите, почтовым адресом. Следовательно, support@example.com и support@example.org представляются отдельными строками в таблице списков рассылки и могут просто сосуществовать в рамках одной системы Mailman.


Далее: Обработчики