Skip to content

Twisted

Twisted - это платформа разработки сетевых приложений на языке Python, управляемых событиями. Эта платформа позволяет решать практически любые задачи, имеющие отношение к работе в сети. Как и любое единое комплексное решение, эта платформа отличается высокой сложностью. Twisted начнет становиться понятной только после неоднократной работы с ней, а в самом начале работа с платформой может оказаться непростым делом. Кроме того, изучение Twisted представляет собой настолько большой труд, что поиск отправного пункта в решении конкретной проблемы часто может оказаться устрашающим.

Тем не менее, мы настоятельно рекомендуем познакомиться с этой платформой и оценить, насколько она соответствует вашему образу мыслей. Если вы легко сможете настроиться на «твистовое» мышление, то изучение платформы Twisted скорее всего будет ценным вложением усилий. Отличной отправной точкой в изучении может служить книга «Twisted Network Programming Essentials» Эйба Феттига (Abe Fettig) (O'Reilly). Она поможет уменьшить влияние отрицательных факторов, о которых упоминалось выше.

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

Какие преимущества вы получите при использовании платформы Twisted? Эта платформа стимулирует, а иногда даже вынуждает вас разбивать свои задачи на маленькие части. Организация сетевого соединения отделена от логики обработки событий, происходящих после установления соединения. Эти два фактора до некоторой степени обеспечивают автоматическую возможность повторного использования вашего программного кода. Еще одно преимущество, которое несет в себе применение платформы Twisted, заключается в том, что вам не придется беспокоиться о низкоуровневых подключениях и заниматься обработкой ошибок, возникающих в них. Ваша основная задача заключается в том, чтобы решить, что необходимо предпринять при появлении определенных событий.

В примере 5.13 приводится сценарий, проверяющий сетевой порт и реализованный на платформе Twisted. Это очень простой сценарий, но он наглядно демонстрирует управляемую событиями природу Twisted, в чем вы убедитесь при изучении пояснений к программному коду. Но перед этим мы коснемся нескольких основных концепций, которые вам необходимо знать. В число этих концепций входят реакторы, фабрики, протоколы и отложенное выполнение. Реакторы - это основа главного цикла обработки событий любого приложения, основанного на платформе Twisted. Реакторы занимаются доставкой событий, сетевыми взаимодействиями и многопоточным выполнением. Фабрики отвечают за создание новых экземпляров протоколов. Каждый экземп-

Twisted

У большинства из тех, кто пишет программный код, складывается отчетливая аналогия логике выполнения программы или сценария: это похоже на ручей, текущий по склону холма, ныряющий в провалы, ветвящийся и т. п. Такой программный код легко писать и отлаживать. Программный код, использующий особенности платформы Twisted, совершенно иной. Вследствие асинхронной природы его скорее можно сравнить с падающими каплями дождя, чем с ручьем, текущим по склону, но на этом аналогии и заканчиваются. Платформа вводит новый компонент: перехватчик событий (реактор) сотоварищи. Чтобы написать и отладить программный код, использующий Twisted, придется отказаться от привычных убеждений и начать изобретать аналогии под другую логику выполнения.

ляр фабрики может порождать экземпляры только одного типа протокола. Протоколы определяют принцип действия определенного соединения. Во время выполнения приложения для каждого соединения создается свой экземпляр протокола. А механизм отложенного выполнения обеспечивает возможность объединения действий в цепочки.

Пример 5.13. Проверка порта, реализованная на платформе Twisted

Обратите внимание, что здесь мы определили два класса (PortChecker-Protocol и PortCheckerClientFactory), каждый из которых наследует классы платформы Twisted. Мы связали свою фабрику PortCheckerClientFactory с PortCheckerProtocol, присвоив класс PortCheckerProtocol атрибуту protocol класса PortCheckerClientFactory. Если попытка установить соединение окончится неудачей, будет вызван метод фабрики сlient-ConnectionFailed(). Метод clientConnectionFailed() является общим для всех фабрик платформы Twisted, и это единственный метод, который мы определили для нашей фабрики. Определяя метод, «поставляемый» вместе с фабричным классом, мы переопределили поведение этого класса, заданное по умолчанию. Когда на стороне клиента попытка установить соединение терпит неудачу, мы выводим соответствующее сообщение и останавливаем работу реактора.

PortCheckerProtocol - это представитель протоколов, о которых говорилось выше. Экземпляр этого класса будет создан сразу же после того, как будет установлено соединение с сервером, порт которого проверяет сценарий. В классе PortCheckerProtocol мы определили единственный метод: connectionMade(). Этот метод является общим для всех классов

 

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

Здесь оба метода- connectionMade() и clientConnectionFailed() - демонстрируют «управляемую событиями» природу платформы Twisted. Установленное соединение - это событие. Точно так же событием является и неудача при попытке установить соединение. Когда возникают такие события, платформа Twisted вызывает соответствующие методы, выполняющие их обработку, которые так и называются — обработчики событий.

В основном разделе этого сценария мы создаем экземпляр класса PortCheckerClientFactory. Затем предписываем реактору платформы Twisted с помощью заданной фабрики выполнить подключение к заданному порту указанного сервера (эти значения передаются сценарию как аргументы командной строки). После того как реактору будет дано указание подключиться к заданному порту указанного сервера, мы запускаем его в работу. Если этого не сделать, тогда вообще ничего не произойдет.

С точки зрения хронологического порядка выполнения можно сказать, что мы запускаем реактор после того, как дадим ему указание. В данном случае было указано установить соединение с портом сервера и использовать класс PortCheckerClientFactory для доставки событий. Если попытка соединения с указанным портом заданного хоста потерпит неудачу, цикл обработки событий вызовет метод clientConnectionFai-led() класса PortCheckerClientFactory. Если соединение будет успешно установлено, фабрика создаст экземпляр протокола PortCheckerProto-col и вызовет метод connectionMade() этого экземпляра. Завершится ли попытка подключения успехом или неудачей, соответствующий обработчик события остановит реактор и программа завершит свою работу.

Это был очень простой пример, но он демонстрирует суть управляемой событиями природы платформы Twisted. Ключевыми концепциями программирования Twisted, которые не были продемонстрированы в этом примере, являются идея отложенного выполнения и функции обратного вызова. Механизм отложенного выполнения берет на себя обязательство выполнить запрошенное действие. А функции обратного вызова обеспечивают способ, дающий возможность определить требуемое действие. Функции, выполняющие отложенные действия, могут объединяться в цепочки и передавать результаты друг другу. Эта особенность платформы Twisted действительно очень сложна для понимания. (Механизм отложенных действий демонстрируется в примере 5.14.)

В примере 5.14 представлен сценарий, использующий брокер перспективы (Perspective Broker) — уникальный механизм вызова удаленных процедур (RPC) в Twisted. Этот пример представляет собой еще одну реализацию сервера «Is», который ранее был реализован с использованием XML-RPC и Pyro. В первую очередь рассмотрим реализацию сервера.

Пример 5.14. Сервер брокера перспективы на платформе Twisted

В этом примере определяется единственный класс, PBDirLister. Это класс брокера перспективы (РВ), который действует как удаленный объект, когда клиент соединяется с ним. В этом примере данный класс определяет всего два метода: remote_ls() и remote_ls_boom(). Метод remo-te_ls() - это один из удаленных методов, которые будут вызываться клиентом. Этот метод remote_ls() просто возвращает содержимое указанного каталога. Метод remote_ls_boom() выполняет те же действия, что и метод remote_ls(), за исключением того, что он не предусматривает обработку исключений. В главном разделе примера мы предписываем брокеру перспективы присоединиться к порту с номером 9876 и запустить реактор.

Пример 5.15. Клиент брокера перспективы платформы Twisted

В этом сценарии клиента определяются три функции: handle_err(), call_ls() и print_ls(). Функция handle_err() обрабатывает все возникающие ошибки. Функция call_ls() инициирует вызов удаленного метода «ls». Функция print_ls() выводит результаты вызова удаленного метода «ls». Может показаться немного странным, что одна функция инициирует вызов удаленного метода, а другая выводит результаты этого вызова. Но, так как Twlsted является асинхронной платформой, управляемой событиями, такое положение вещей обретает определенный смысл. Сама платформа способствует созданию программного кода, который делит работу на мелкие части.

В основном разделе примера видно, как реактор определяет, когда и какие функции обратного вызова следует вызывать. Сначала мы создаем фабрику клиента брокера перспективы и предписываем реактору выполнить подключение к порту 9876 сервера localhost, используя фабрику клиента РВ для обработки запросов. Затем вызовом метода facto-гу. getRootObject() создается заготовка удаленного объекта. Фактически это объект отложенного действия, поэтому мы имеем возможность объединить действия в конвейер, вызвав метод addCallback() объекта.

Первой функцией обратного вызова, которую мы добавляем, является функция call_ls(). Функция call_ls() вызывает метод remote_ls() объекта отложенного действия, созданного на предыдущем шаге. Метод call Remote () возвращает сам объект. Вторая функция обратного вызова в цепочке обработки - это функция print_ls(). Когда реактор вызывает print_ls(), она выводит результаты обращения к удаленному методу remote_ls() на предыдущем шаге. Фактически реактор передает результаты вызова удаленного метода функции print_ls(). Третья функция обратного вызова в цепочке - handle_err(), которая является обычным обработчиком ошибок, она просто сообщает о появлении ошибок в процессе работы. Когда в ходе выполнения возникает ошибка или когда процесс достигает функции print_ls(), соответствующие методы останавливают реактор.

Результат работы клиентского сценария выглядит, как показано ниже:

Вывод представляет собой список файлов в указанном каталоге, именно это мы и ожидали получить.

Этот сценарий выглядит несколько сложнее, чем можно было ожидать для такого простого примера RPC. Серверный сценарий выглядит сопоставимым. Создание клиента выгдядит несколько перегруженным из-за объединения функций обратного вызова в конвейер, создания объекта отложенного действия, реакторов и фабрик. Но это был очень простой пример. Преимущества платформы Twlsted проявляются особенно ярко, когда задача, которую требуется решить, имеет более высокий уровень сложности.

В примере 5.16 представлена немного модифицированная версия только что продемонстрированного клиента брокера перспективы. Вместо удаленной функции ls он вызывает удаленную функцию ls_boom. Этот пример демонстрирует, как производится обслуживание исключений на стороне клиента и сервера.

Ниже показано, что произошло, когда мы запустили этот сценарий:

И на стороне сервера:

Пример 5.16. Клиент брокера перспективы платформы Twlsted -обработка ошибок

Конкретное сообщение об ошибке появилось на стороне сервера, а не на стороне клиента. На стороне клиента мы лишь увидели, что произошла какая-то ошибка. Если бы Руго или XML-RPC вели себя подобным образом, мы посчитали бы, что это недостаток. Но ведь наш обработчик ошибки был вызван в клиентском сценарии, реализованном на платформе Twisted. Так как эта модель программирования (основанная на событиях) отличается от модели программирования, применяемой при использовании Руго и XML-RPC, мы предполагаем, что обработка ошибок будет производиться иначе, и программный код брокера перспективы сделал именно то, что мы должны были ожидать от него.

Здесь мы представили вашему вниманию даже меньше, чем вершину айсберга Twisted. На первых порах работа с платформой Twisted может оказаться достаточно сложным делом из-за такой широты возможностей этого проекта и подходов к решению задач, так не похожих на то, к чему привыкло большинство из нас. Платформа Twisted определенно заслуживает внимательного изучения и включения ее в свой арсенал.

Комментарии (0)

RSS feed Comments

Написать комментарий

smaller | bigger

busy
 

Регистрация




Top