SK Telecom
- 1 year ago
- 0
- 0
Open Telecom Platform , OTP , Erlang/OTP («открытая телекоммуникационная платформа») — программный каркас (фреймворк) , содержащий набор библиотек и шаблонов проектирования для построения масштабируемых распределённых приложений на языке программирования Erlang .
Фреймворк создан в компании Ericsson в рамках проекта ATM-маршрутизаторов серии AXD в одноимённом производственном подразделении и выпущен в 1996 году , воплотив многолетний опыт по созданию отказоустойчивых систем .
Высокая надёжность приложений возможна благодаря простому, но мощному механизму обработки исключений, на основе которых были построены обобщённые библиотеки. Используя библиотеки фреймворка OTP, разработчик на Erlang программирует требуемое поведение, а библиотеки занимаются обработкой исключений. Такой подход делает код короче и обычно вносит меньше ошибок .
В своей диссертации Джо Армстронг объясняет выбранный в OTP подход к программированию высоконадёжных систем необходимостью абстрагирования от параллельного исполнения ( англ. abstracting out concurrency ): отлаженный и проверенный в работе OTP берёт заботу о параллельном исполнении на себя, тогда как менее квалифицированные прикладные программисты могут создавать остальные компоненты в более простом и знакомом им «последовательном» стиле .
Формализацией шаблонов проектирования, характерных для конкурентного программирования, являются поведения ( англ. behaviors ), реализованные в виде модулей стандартной библиотеки Erlang. В модулях определяется обобщённая функциональность для процессов некоторого типа. Программисту требуется лишь создать свой модуль с функциями обратного вызова ( англ. callback functions ), конкретизирующий функциональность.
Поведение OTP строится из рабочих процессов ( англ. worker process ) и процессов-наблюдателей ( англ. supervision process ), составляющих дерево наблюдения ( англ. supervision tree ).
Модули и деревья наблюдения вместе образуют OTP-приложение (не следует путать с приложением в смысле готового программного продукта). OTP-приложение — компонент, реализующий некоторую функциональность, которая может быть независимо запущена на исполнение и остановлена как целое, а также повторно использована в других системах . Примером приложения, входящего в состав Erlang/OTP, может служить Mnesia .
Взаимодействия модуля поведения и модуля функций обратного вызова происходит по схеме :
Модуль поведения содержит общую для процессов некоторого типа функциональность, включающую в себя характерные операции :
Специфичная функциональность описывается программистом в модуле функций обратного вызова и включает следующее :
Таким образом, в поведении можно выделить следующие части :
Некоторое поведение является как бы образцом для конкретного «типа» процессов (например, процессы типа
gen_fsm
). Говоря неформально, процессы одного «типа» выполняют примерно одинаковый код, а значит — «понимают» определённый набор сообщений. Процессы одного «типа» отличаются только своим индивидуальным состоянием. Между процессами и объектами
ООП
можно проследить достаточно чёткую аналогию, с той возможной разницей, что процессы выполняются независимо и конкурентно
.
Обобщённый сервер реализует модель клиент-сервер . Начало модуля функций обратного вызова для этого поведения может в минимальном случае выглядеть примерно таким образом :
-module(myserver).
-behaviour(gen_server).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
% далее следует описание функций, относящихся к интерфейсу поведения
Кроме функций обратного вызова модуль может содержать функции
API
. В случае
gen_server
такими функциями могут быть запуск процесса, а также отправка синхронных и асинхронных сообщений этому процессу. Функции API обычно являются обёртками для вызова соответствующих функций библиотеки. Продолжая предыдущий пример
:
-export([start_link/1, get_something/0, stop/0]).
start_link(Port) -> gen_server:start_link({local, ?SERVER}, ?MODULE, [Port], []).
% далее следуют другие функции, объявленные в директиве экспорта
Документация по Erlang/OTP даёт описание функций модуля поведения и связанных с ними функций обратного вызова в виде таблицы .
Модуль обобщённого сервера
gen_server:
|
Модуль функций обратного вызова |
---|---|
start_link
|
init/1
|
call, multi_call
|
handle_call/3
|
cast, abcast
|
handle_cast/2
|
-
|
handle_info/2
|
-
|
terminate/2
|
-
|
code_change/3
|
Поведение для организации обработки событий, во многом похожий на
gen_server
по набору функций. Важным отличием
gen_event
от
gen_server
является возможность динамически добавлять или убирать несколько обработчиков событий, тогда как обобщённый сервер получает модуль функций обратного вызова при запуске. Так как обработкой событий занимаются различные модули, следует проявлять осторожность в обращении с состоянием цикла
.
Нечасто используемое поведение, которое позволяет организовать логику конечного автомата .
В задачи наблюдателя входит запуск, остановка и слежение за дочерними процессами, которые в свою очередь могут быть процессами-наблюдателями и рабочими процессами других типов
. Корневой наблюдатель, то есть, наблюдатель приложения, следящий за другими процессами, обычно получает имя вида
название_приложения_sup
.
В контексте OTP приложение имеет особый смысл — это программный компонент (или
метаданных
, имеющих определённую соглашением структуру файлов на диске
. Приложение OTP может быть запущено и остановлено Erlang-системой как единое целое по имени. Модуль поведения
application
обычно имеет имя вида
имя_приложения_app
и требует экспорта всего двух функций:
start/1
и
stop/1
.
Erlang/OTP предлагает разработчикам приложений следующие возможности :
Язык Elixir позволяет использовать поведения и приложения OTP. Следующий пример показывает сервер, вычисляющий значение функции. Все функции, связанные с работой сервера, делегированы GenServer :
defmodule Dup.Server do
use GenServer
def handle_call(:calc_double, _from, x) do
{:reply, x, 2 * x}
end
end
Функция
handle_call
получает от (игнорируемого в данном примере) клиента
_from
, а также текущее состояние сервера
x
. Возвращает текущее состояние и удваивает переменную состояния.
{{
cite conference
}}
:
Неизвестный параметр
|booktitle=
игнорируется (
|book-title=
предлагается) (
справка
)
;
Неизвестный параметр
|month=
игнорируется (
справка
)