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

UnixForum





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

GNU Mailman

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

Оригинал: GNU Mailman
Автор: Barry Warsaw
Дата публикации: 27 Апреля 2012 г.
Перевод: А.Панин
Дата перевода: 19 Июня 2013 г.

Creative Commons: Перевод был сделан в соответствие с лицензией Creative Commons. С русским вариантом лицензии можно ознакомиться здесь.

GNU Mailman является свободным программным обеспечением для управления списками рассылки. Практически каждый, кто разрабатывает или использует свободное программное обеспечение, сталкивался со списком рассылки. Списки рассылки могут использоваться для дискуссий или объявлений, а также одновременно для двух этих целей в различной мере. Иногда списки рассылки связаны с группами новостей в Usenet или такими подобными Usenet сервисами, как Gmane. Списки рассылки обычно используют архивы, содержащие историю всех отправленных в них сообщений.

Система GNU Mailman используется с начала 1990 года, когда John Viega разработал ее первую версию для объединения фанатов недавно организованной группы Dave Matthews Band, члены которой были друзьями в колледже. Эта первая версия привлекла внимание сообщества разработчиков языка Python в середине 90 годов, когда центр вселенной Python переместился из научно-исследовательского института Нидерландов CWI в национальную корпорацию исследовательских инициатив CNRI в городе Reston, штат Virginia, США. В CNRI для управления различными связанными с языком Python списками рассылок мы использовали систему Majordomo, которая была разработана с использованием языка программирования Perl. Конечно же, работающим с языком Python людям было неудобно поддерживать такой большой объем кода Perl. А еще более важным является то, что мы столкнулись со значительными сложностями при модификации приложения Majordomo для наших целей (например, при добавлении простейших возможностей для борьбы со спамом), обусловленными выбранной архитектурой приложения.

Ken Manheimer играл ведущую роль в разработке начальных версий системы GNU Mailman, при этом множество замечательных разработчиков сделало свой вклад в разработку с того момента. На сегодняшний день Mark Sapiro поддерживает стабильную ветку 2.1 в то время, как автор данной главы Barry Warsaw работает над новой версией 3.0.

Многие из оригинальных архитектурных решений, принятых John Viega, дожили в форме кода до версии 3 системы Mailman и все еще могут быть изучены при исследовании кода стабильной версии. В следующих разделах я опишу некоторые из наиболее проблемных архитектурных решений в рамках версий 1 и 2 системы Mailman, а также наши подходы к решению данных проблем в версии 3.

В начале периода эксплуатации версии 1 системы Mailman мы испытывали множество проблем, заключающихся в потере сообщений или в ошибках, приводящих к бесконечной доставке одних и тех же сообщений. Это обстоятельство подтолкнуло нас к четкой формулировке двух основных принципов, являющихся критическими для будущего успешного развития системы Mailman:
  • Ни одно из сообщений не должно быть потеряно.
  • Ни одно из сообщений не должно быть доставлено более чем единожды.

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

10.1. Анатомия сообщения

Одной из основных структур данных системы Mailman является сообщение электронной почты (email message), представленное объектом message. Многие интерфейсы, функции и методы в рамках системы принимают три аргумента: объект списка рассылки, объект сообщения и словарь метаданных, используемый для записи и обмена данными состояния в ходе обработки сообщения системой.

Сообщение, содержащее текст, изображения и звуковой файл; тип MIME
Рисунок 10.1: Сообщение, содержащее текст, изображения и звуковой файл; тип MIME

При подробном рассмотрении сообщение электронной почты оказывается простым объектом. Оно состоит из множества разделенных точкой с запятой пар ключ-значение, называемых заголовками, после которых следует пустая строка, отделяющая заголовки от сообщения. Это текстовое представление должно облегчать разбор, генерацию, исследование и манипуляции с сообщениями, но на самом деле оно стремительно усложнилось. Существует несчетное количество стандартов RFC, которые описывают все вероятные возможности, такие, как обработка сложных типов данных, представленных изображениями, аудиофайлами и другими типами. Сообщение электронной почты может содержать текст на английском языке в кодировке ASCII или текст на любом другом языке в любой существующей кодировке. Основная структура сообщения электронной почты заимствовалась снова и снова для использования в рамках других протоколов, таких, как NNTP и HTTP, причем все эти протоколы отличаются в значительной степени. В ходе нашей работы над системой Mailman была начата разработка нескольких библиотек исключительно для обработки всех возможных случаев использования данного формата (обычно называемого "RFC822" в соответствии с принятым в 1982 году стандартом IETF). Библиотеки для работы с сообщениями электронной почты, изначально разрабатываемые для применения в рамках системы GNU Mailman, были включены в стандартную библиотеку языка Python, где их разработка продолжилась в направлении улучшения стабильности работы и соответствия стандартам.

Сообщения электронной почты могут выступать в качестве контейнеров для других типов данных, как это описано в различных стандартах MIME. Контейнер сообщения (container message part) может содержать закодированное изображение, аудиофайл или любые бинарные или текстовые данные, включая другие контейнеры. В приложениях для работы с электронной почтой они известны под названием "вложения" (attachments). На Рисунке 10.1 показана структура сложного сообщения MIME. Прямоугольники со сплошными границами являются контейнерами, прямоугольники со штриховыми границами являются закодированными с помощью алгоритма Base64 бинарными данными, а прямоугольник с пунктирными границами - текстовым сообщением.

Контейнеры могут также быть произвольно вложенными; в этом случае они называются мультиконтейнерами (multipart) и фактически могут находиться на достаточно глубоком уровне вложенности. При этом любое сообщение электронной почты, независимо от его сложности, может быть представлено в виде дерева с единственным объектом сообщения на вершине. В рамках системы Mailman мы обычно рассматриваем сообщение как дерево объектов (message object tree) и передаем это дерево, ссылаясь на основной объект сообщения. На Рисунке 10.2 показано дерево объектов сообщения с мультиконтейнерами, схематично изображенного на Рисунке 10.1.

Дерево объектов для сложного MIME-типа сообщения электронной почты
Рисунок 10.2: Дерево объектов для сложного MIME-типа сообщения электронной почты

Система Mailman практически всегда модифицирует оригинальное сообщение каким-либо образом. Иногда трансформации могут быть весьма незначительными, заключающимися в добавлении или удалении заголовков. Иногда мы полностью изменяем структуру дерева объектов сообщения, например, в том случае, когда фильтр содержимого удаляет определенные типы данных, такие, как текст в формате HTML, изображения или другие не текстовые данные. Система Mailman может даже удалить описание типа MIME "multipart/alternatives" в том случае, если сообщение содержит и текстовую часть и текстовые данные, использующие какой-либо тип разметки, или добавить дополнительные части сообщения, содержащие информацию о списке рассылки.

В общем случае система Mailman разбирает актуальное (on the wire) байтовое представление сообщения всего один раз в тот момент, когда сообщение передается системе. С этого момента система работает только с деревом объектов сообщения до тех пор, пока оно не готово для отправки на используемый почтовый сервер. В этот момент система Mailman преобразует дерево объектов обратно в байтовое представление. В ходе обработки сообщения Mailman сохраняет дерево объектов сообщения (с помощью модуля pickle) для хранения и последующего извлечения из файловой системы. Модуль pickle предоставляет функции, реализующие технологию языка Python для преобразования любого объекта Python, включая все его дочерние объекты, в последовательность байт (сериализации) и отлично подходит для оптимизации процесса обработки деревьев объектов сообщений электронной почты. Также доступна функция преобразования этой последовательности байт в активный объект (десериализации). Храня эти последовательности байт в файлах, программы на языке Python получают в свое распоряжение постоянное хранилище данных, требующее малых затрат ресурсов.


Далее: Список рассылки