Главная
страница 1 ... страница 3страница 4страница 5страница 6

3.4 Сервер приложений

Для использования возможностей web-разработки с использованием продолжений в рамках проекта был реализован многопроцессный HTTP-сервер. Выбор в пользу многопроцессного сервера был сделан по причине того, что интерпретатор Python обладает немалым количеством ошибок, которые проявляются при работе с потоками. Это делает работу с потоками в Python не только сложной, но и опасной.

Одной из главных проблем многопотокового программирования как в Python, так и в Stackless, является GIL (от англ. Global Interpreter Lock – «глобальная блокировка интерпретатора»). При своей работе Python использует большое количество потоково-небезопасных данных. Во избежание разрушения этих данных при совместной модификации из разных потоков перед началом исполнения нескольких инструкций поток интерпретатора захватывает GIL, а по окончанию – освобождает. Вследствие этой особенности в каждый момент времени может исполняться только один поток Python кода, даже если на компьютере имеется несколько процессоров или процессорных ядер. Поэтому для параллельного исполнения нескольких потоков Python кода рекомендуется использовать процессы.

Для этих целей существует модуль processing, который имитирует семантику стандартного модуля threading, но использует процессы вместо потоков. Этот модуль поддерживает очереди, каналы (англ. pipes), блокировки, а так же разделяемые переменные. Этого набора достаточно, чтобы реализовать многопроцессный HTTP-сервер в многопотоковом стиле.

В итоге для реализации HTTP-сервера было решено помимо модуля processing воспользоваться базовым кодом HTTP-сервера из модуля BaseHTTPServer. Итак, при запуске реализованного HTTP-сервера создается экземпляр класса HTTPServer, который открывает на прослушивание сокет на указанном IP-адресе и порту, после чего процесс разветвляется на заданное количество дочерних процессов.

Для обработки запросов с выполнением продолжений необходимо было перегрузить метод process_request(), в котором происходит извлечение идентификатора продолжения и определяется функция-обработчик, необходимая для обработки запроса. Далее управление передается разработанным базовым модулям, которые выполняют свои функции.


3.5 Интеграция с Django

Реализованный HTTP-сервер позволяет воспользоваться возможностями разработки web-приложений с использованием продолжений, но не является законченным решением для создания сложных web-приложений. С целью повышения эффективности разработки сложных web-приложений было необходимо рассмотреть возможность интеграции основных фрагментов разработанной системы управления продолжениями с существующими программными решениями.

Django является высокоуровневым бесплатным программным каркасом для создания web-приложений, написанный на языке программирования Python. Он обладает прагматичным дизайном и позволяет эффективно разрабатывать сложные web-приложения. Он примерно соответствует архитектуре MVC, хотя сами создатели называют ее MTV (от англ. Model-Template-View – «Модель-Шаблон-Вид»), где в роли контроллера выступает вид (функция-обработчик).

Изначально Django использовался в рабочем режиме в World Company для управления тремя новостными сайтами. Это происхождение не могло не сказаться на архитектуре каркаса: он предоставляет ряд средств, которые помогают в быстрой разработке web-приложений информационного характера. Так, например, в Django имеется встроенная расширяемая система администрирования сайта, позволяющая управлять его содержимым[8].

Кроме того, в возможности Django входят:


  • Встроенный слой ORM (от англ. Object-relational mapping – «Объектно-реляционная проекция») – технология, которая связывает базу данных с концепциями объектно-ориентированных языков программирования, создавая «виртуальную объектную среду».

  • Подключаемая архитектура приложений, которыми можно компоновать целевую информационную систему.

  • Полноценный API доступа к базе данных с поддержкой транзакций.

  • Авторизация пользователей с возможностью подключения внешних модулей авторизации.

  • Расширяемая система шаблонов, поддерживающая наследование.

  • Диспетчер URL, построенный на регулярных выражениях

  • Система фильтров (англ. middleware) для построения дополнительных обработчиков запросов.

  • Интернационализация и локализация приложений

Этот список возможностей может быть продолжен. Именно благодаря выдающимся возможностям этого программного каркаса с целью расширить эти возможности было решено интегрировать Django с разработанными для поддержки web-разработки с продолжениями базовыми модулями.

Для решения поставленной задачи было решено воспользоваться системой фильтров. Django позволяет создавать легковесные низкоуровневые фильтры для обработки приходящих запросов и выходящих ответов.





Рисунок 12. Обработка запроса сервером приложений.

DFD-диаграмма верхнего уровня
Запрос программы-клиента в Django обрабатывается следующим образом. При получении запроса центральный процессор событий проверяет строку запроса на соответствие зарегистрированным в системе регулярным выражениям. При совпадении процессор выбирает соответствующую функцию-обработчик. Далее функция обработчика и параметры запроса пропускаются через систему фильтров. Если ни один из фильтров не вернул ответа, то управление передается функции-обработчику, которая после выполнения возвращает объект ответа в центральный процессор, которой вновь прогоняется через зарегистрированные фильтры. После этого ответ возвращается программе-клиенту (см. Рисунок 13).

Таким образом, было необходимо реализовать фильтр для запроса, который определял бы тип функции-обработчика, при необходимости извлекал и восстанавливал продолжение или создавал новое. Такая необходимость возникает не всегда: не следует забывать про встроенную в Django подсистему администрирования, которая должна была продолжать работать в штатном режиме. В ходе экспериментов было выявлена невозможность реализации функций-обработчиков с поддержкой продолжений идентичными оригинальным функциям-обработчикам. Это связанно с тем, что Django при передаче управления своим функциям-обработчикам передает им объект запроса в качестве параметра. А при сериализации функции-обработчика с поддержкой продолжения полученный параметр сохранится, но при восстановления продолжения система должна передать ему новый объект запроса. Чтобы избежать подобного конфликта, было предоставить доступ к объекту запроса, через глобальную переменную, которая, как было описано выше, не сохраняется вместе с продолжением.





Рисунок 13. DFD-диаграмма декомпозиции функции «Сервера приложений»
В итоге для создания функции-обработчика с поддержкой продолжения необходимо после объявления установить ей атрибут, по которому фильтр сможет определить, обрабатывать ему этот запрос или нет.



Рисунок 14. DFD-диаграмма декомпозиции функции «фильтра»,

отвечающего за управление состояниями
Django имеет встроенную поддержку FastCGI – один из наиболее производительных и безопасных способов обработки запросов внешними программами. FastCGI ликвидирует множество ограничений CGI-программ, такие как необходимость перезапуска web-сервером при каждом запросе, приводящую к понижению производительности. FastCGI убирает это ограничение, сохраняя процесс запущенным и передавая запросы этому постоянно запущенному процессу, что позволяет экономить время на создание новых процессов[9]. FastCGI поддерживается в Django как в многопотоковом, так и в многопроцессном режиме.

При реализации хранилища продолжений для Django с целью избежать лишних нагрузок на актуализацию хранимых состояний было решено использовать встроенных механизм пользовательских сессий. Пользовательские сессии Django также хранятся в базе данных, но имеют свое «время жизни». Кроме того, использование пользовательских сессий в качестве хранилища продолжений позволяет повысить безопасность приложений за счет того, что злоумышленник при перехвате идентификатора продолжения не сможет его загрузить, если соответствующее состояние не сохранено в его сессии.

Таким образом, программный каркас Django был расширен новой возможностью поддержки функций-обработчиков с продолжением, сохранив при этом все свои достоинства.



Листинг 3. Вид Django-обработчика многошаговой бизнес-функции

с использованием продолжений

На Листинге 3 представлен код примера, получившейся в результате функции обработчика Django. Объект запроса является атрибутом объекта cont, класс которого содержит в себе управляющие статические методы send() и send_and_wait(). Кроме того, во вспомогательной функции process_template(), которая генерирует ответ, основываясь на выходных параметров, используется метод current(), который возвращает идентификатор текущего состояния, по которому будет сохранено продолжение выполняющейся функции.


Заключение


В заключение стоит отметить все преимущества, которые дают продолжения при разработке сложных web-приложений.

Главным преимуществом разработки web-приложений, основанной на продолжениях, является то, что логика приложения описывается последовательностью шагов алгоритма. Безусловно, система остается разбита на определьнное количество логических компонент, но связи между этими компонентами обусловлены взаимодействием и потоком данных, которые успешно описыавют логику всего приложения. Таким образом, достигается сближение методик разработки «настольных» приложений и web-приложений. Появляется возможность логикой приложения описать работу бизнес-функций, включая управление обменом данными между пользователем и системой, что является невозможным при традиционном подходе к разработке web-приложений.

Кроме того, такой подход позволяет разработчику абстрагироваться от того, что система взаимодействует с программой-клиентом (браузером), предоставляющей альтернативные, непредусмотренные системой способы навигации.

Важную роль играет и то, что у разработчика нет необходимости беспокоиться за сохранение данных между транзакциями. Продолжения, сохраняя вместе с указателем на следующую инструкцию все свое локальное окружение, решают эту проблему за него.

Таким образом, разработанная библиотека избавляет Python программистов от ряда проблем при разработке и поддержке комплексных web-приложений.

Результатом работы стал разработанный многопроцессный HTTP-сервер, основанный на продолжениях, который предоставляет ряд API-вызовов, позволяющих управлять обменом данными между клиентом и сервером.



Кроме того, была произведена интеграция основных функций, позволяющих использовать продолжения для написания приложений, с популярным программным каркасом Django, что дает разработчикам дополнительные возможности при разработке сложных web-приложений. Возможности Django вместе с интегрированными API-вызовами управления обменом данными между клиентом и сервером образуют мощный инструментарий для эффективной разработки производительных информационных систем.

Список использованных источников




  1. Belapurkar A. Use continuations to develop complex Web applications // IBM developerWorks [Электронный ресурс]. – 2004. – Режим доступа: http://www.ibm.com/developerworks/library/j-contin.html, свободный.

  2. Continuation // Wikipedia, the free encyclopedia [Электронный ресурс]. – 2005. – Режим доступа: http://en.wikipedia.org/wiki/Continuation, свободный.

  3. Мельтцер К., Михальски Б. Разработка CGI-приложений на Perl – Пер. с англ. – М.: Вильямс, 2001. – 400с.

  4. Собчук А. Продолжение всемирной паутины // SmallTalk по-русски [Электронный ресурс]. – 2004. – Режим доступа: http://www.smalltalk.ru/articles/web-continuations.html, свободный.

  5. Control Flow // Apache Cocoon Project [Электронный ресурс]. – 2008 – Режим доступа: http://cocoon.apache.org/2.1/userdocs/flow/index.html, свободный.

  6. Closure (computer science) // Wikipedia, the free encyclopedia [Электронный ресурс]. – 2005. – Режим доступа: http://en.wikipedia.org/wiki/Closure_%28computer_science%29, свободный.

  7. About Stackless // Stackless Python [Электронный ресурс]. – 2008. – Режим доступа: http://www.stackless.com/, свободный.

  8. Django Documentation // Django [Электронный ресурс]. – 2007. – Режим доступа: http://www.djangoproject.com/documentation, свободный.

  9. FastCGI // Wikipedia, the free encyclopedia [Электронный ресурс]. – 2007. – Режим доступа: http://en.wikipedia.org/wiki/FastCGI, свободный.

Приложение А. Руководство системного программиста


Основные классы системы можно разделить на три части: менеджер продолжений, хранилище состояний и функции пользовательского API.



Рисунок 125. Диаграмма классов и микропотоков

системы управления продолжениями
Хранилище состояний

Функция cont.storage.load_storage() (cont/storage/__init__.py)

Описание: представляет собой «фабрику» хранилищ состояний, которая создает объект хранилища по запрошенному типу.

Аргументы:

  • string storage_type – строка с именем класса используемого хранилища состояний.

Возвращает: cont.storage.base.Storage storage – экземпляр класса запрошенного хранилиша состояний.

Класс cont.storage.base.State (cont/storage/base.py)

Описание: является базовым абстрактным классом состояния, в котором определены необходимые менеджеру управления атрибуты и методы.

Аттрибуты:

  • stackless.Tasklet tasklet – микропоток функции-обработчика.

  • str|int parent_id – идентификатор предыдущего состояния.

  • int created – время создания состояния.

  • cont.storage.base.Storage storage – экземпляр класса используемого хранилища.

Методы:

  • public id()

Описание: генерирует идентификатор состояния

Возвращает: int|string identifier – идентификатор состояния.

  • public parent()

Описание: предоставляет доступ к родительскому узлу в дереве состояний.

Возвращает: cont.storage.base.State state – предыдущее состояние.

Класс cont.storage.base.Storage (cont/storage/base.py)

Описание: является базовым абстрактным классом хранилища состояний.

Методы:

  • public serialize()

Описание: сериализует указанное состояние в строку.

Аргументы:

    • cont.storage.base.State state – объект состояния.

Возвращает: string state_string – результат сериализации.

  • public deserialize()

Описание: восстанавливает объект состояния из строки.

Аргументы:

    • string state_string – результат сериализации состояния.

Возвращает: cont.base.Storage.State state – восстановленное состояние.

  • public create()

Описание: виртуальный метод, реализация которого должна создавать новое состояние.

Аргументы:

    • stackless.Tasklet tasklet – микропоток функции-обработчика.

    • int|string parent_id – идентификатор состояния-родителя в дереве состояний.

Возвращает: cont.storage.base.State state – новое состояние.

  • public load()

Описание: виртуальный метод, реализация которого должна загружать состояние из хранилища.

Аргументы:

    • int|string state_id – идентификатор состояния.

Возвращает: cont.storage.base.State state – запрошенное состояние.

  • public store()

Описание: сохраняет состояние в хранилище.

Аргументы:

    • cont.storage.base.State state – состояние для сохранения.

  • public id()

Описание: виртуальный метод, реализация которого должна генерировать идентификатор состояния.

Аргументы:

    • cont.storage.base.State state – запрошенное состояние.

Возвращает: int|string state_id – идентификатор состояния.

Менеджер управления

Класс Manager (cont/__init__.py)

Описание: является основным в работе системы.

Аттрибуты:

  • stackless.Channel channel – канал для коммуникации между менеджером состояний и функцией-обработчиком.

  • cont.storage.base.Storage storage – хранилище продолжений.

  • HttpRequest request – слот для объекта запроса.

  • cont.storage.base.State current – начальное состояние текущего продолжения.

Методы:

  • public page()

Описание: создает новый тасклет, в котором запускается функция обработчик и передает ему управление.

Аргументы:

    • function page – запрошенная функция-обработчик.

    • HttpRequest request – объект запроса.

Возвращает: см. метод _continue().

  • public cont()

Описание: загружает по идентификатору состояние и передает управление тасклету, хранящемуся в нем.

Аргументы:

    • int|string state_id – идентификатор состояния.

    • HttpRequest request – объект запроса.

Возвращает: см. метод _continue().

  • private _continue()

Описание: открывает канал на чтение, тем самым переключая систему с микропотока менеджера состояний на микропоток функции-обработчика. Считывает результат выполнения функции-обработчика, сохраняет новое состояние и возвращает ответ системы.

Возвращает: HttpResponse response – ответ системы.

Функции пользовательского API

Класс Api (cont/__init__.py)

Аттрибуты класса:

  • Manager manager – менеджер продолжений.

Методы класса:

  • public current()

Описание: генерирует идентификатор начального состояния текущего продолжения.

Возвращает: int|string state_id – идентификатор состояния.

  • public request()

Описание: обеспечивает доступ к объекту запроса.

Возвращает: HttpResponse response – объект запроса.

  • public send_and_wait()

Описание: записывает в канал данные об ответе функции-обработчика, тем самым переключая управление на микропоток менеджера продолжений.

Аргументы:

    • HttpResponse response – объект ответа

  • public send ()

Описание: записывает в канал данные об ответе функции-обработчика, тем самым переключая управление на микропоток менеджера продолжений. Кроме того записывает в канал информацию о том, что транзакция завершена.

Аргументы:

    • HttpResponse response – объект ответа

Приложение Б. Руководство прикладного программиста Django


Прежде всего в файле настроек Django необходимо в секцию MIDDLEWARE_CLASSES добавить последним элементом cont.django.ContimuationMiddleware

Чтобы воспользоваться предоставляемыми библиотеками функциями API, их необходимо загрузить класс Api из модуля cont.



Создание функции-обработчика с продолжением имеет ряд незначительных отличий от создания оригинальных функций-обработчиков Django:

  • Доступ к объекту запроса осуществляется через обращение к методу Api.request() импортируемого из библиотеки объекта cont, а не через параметр функции-обработчика.

  • Функция-обработчик возвращает значение не с помощью конструкции «return», а как аргумент функции Api.send_and_wait(), если необходимо продолжить выполнение кода, или функции Api.send() при завершении работы функции-обработчика. Обе эти функции импортируются из библиотеки.

  • Необходимо функции-обработчику установить значение атрибут cont в True.

Получение идентификатора текущего продолжения можно получить через вызов функции Api.current(), также импортируемой из библиотеки. Его необходимо передавать с каждым запросом от программы-клиента в качестве параметра с именем «__continue».

Приложение В. Файлы проекта


  • cont/__init__.py – содержит классы Handle и Api

  • cont/storage/__init__.py – содержит функцию load_storage()

  • cont/storage/base.py – содержит абстрактные классы Storage и State

  • cont/storage/mem.py – содержит классы Storage и State для организации хранилища состояний в памяти

  • cont/django/storage.py – содержит классы Storage и State для организации хранилища состояний в пользовательской сессии Django

  • cont/django/__init__.py – содержит класс ContinuationMiddleware – фильтр Django


<< предыдущая страница  
Смотрите также:
С. А. Юшкеев Электронная версия дипломной работы помещена в электронную библиотеку. Файл
392.45kb.
6 стр.
Памятка системному администратору 7 Работа с базой данных 11 Состав и структура базы 11 Сортировка документов 17
471.58kb.
8 стр.
Пример оформления задания по дипломной работе
29.14kb.
1 стр.
Руководство по технической поддержке Руководство касается программы e-staff Рекрутер, версия 2 Однопользовательская версия
55.13kb.
1 стр.
Требования по оформлению
150.55kb.
1 стр.
Арутюнян гагик гарушевич конституционный суд
3096.3kb.
13 стр.
Название издания
35.49kb.
1 стр.
Дипломной работы
53.73kb.
1 стр.
Методические указания к выполнению дипломной работы
345.3kb.
1 стр.
Old Good Stalker Mod: Clear Sky история изменений версия 8 Community
553.99kb.
3 стр.
Положение о дипломной работе студента факультета психологии и социальной работы по специальности педагогика и психология
254.18kb.
1 стр.
Электронная версия
45.86kb.
1 стр.