OTP System Gen Server
Материал из Erlang по-русски.
Содержание |
gen_server
Автор: Didro
Дата: 29.10.200\6
Версия: 1.0
Название модуля
gen_server
Краткое описание
Шаблон поведения обобщённого сервера
Описание
Базовый модуль, реализующий шаблон поведения сервера в рамках клиент-серверной модели. Реализованный с помощью этого модуля серверный процесс будет обладать стандартным набором интерфейсных функций, включая отладку и мониторинг ошибок. Данный процесс может быть частью OTP-дерева супервизоров. Более подробная информация приведена в OTP Design Principles. Дизайн данного серверного процесса предполагает, что весь специфичный, проблемно-ориентированный код сосредоточен в callback-модуле, который экспортирует набор предопределенных функций. Отображение функций шаблонного модуля на функции callback-модуля показано ниже:
Шаблонный (gen_server) модуль Callback-модуль ----------------------------- --------------- gen_server:start_link -----> Module:init/1 gen_server:call gen_server:multi_call -----> Module:handle_call/3 gen_server:cast gen_server:abcast -----> Module:handle_cast/2 - -----> Module:handle_info/2 - -----> Module:terminate/2 - -----> Module:code_change/3
Если при выполнении callback-функции возникает ошибка или если callback-функция возвращает некорректное значение, то работа gen_server будет прекращена. Имеется возможность использования модуля sys для отладки gen_server. Процесс gen_server не обрабатывает сигнал exit автоматически, обработка данного сигнала должна быть реализована вами в callback-модуле. Если такая функция не определена, то все функции в данном модуле будут завершаться неудачно, если указанный gen_server не существует или если получен некорректный аргумент. Экспортируемые функции
start_link(Module, Args, Options) -> Result
start_link(ServerName, Module, Args, Options) -> Result
Типы:
ServerName = {local,Name} | {global,GlobalName}
Name = atom()
GlobalName = term() Module = atom() Args = term()
Options = [Option]
Option = {debug,Dbgs} | {timeout,Time} | {spawn_opt,SOpts}
Dbgs = [Dbg]
Dbg = trace | log | statistics | {log_to_file,FileName} | {install,{Func,FuncState}}
SOpts = [term()]
Result = {ok,Pid} | ignore | {error,Error}
Pid = pid()
Error = {already_started,Pid} | term()
Данная функция создаёт процесс gen_server как часть дерева супервизоров. Функция может быть вызвана супервизором как явно, так и косвенно. Кроме прочих действий, функция проверяет (гарантирует?), связан ли процесс gen_server с супервизором.
Процесс gen_server вызывает функцию Module:init/1 для инициализации сервера. Для синхронизации процедуры запуска сервера, функция start_link/3,4 не возвращает управление до тех пор, пока не завершится выполнение функции Module:init/1. Если ServerName={local,Name}, то gen_server будет локально зарегистрирован под именем Name с помощью вызова функции register/2. Если ServerName={global,GlobalName}, то будет проведена глобальная регистрация gen_server под именем GlobalName с помощью функции global:register_name/2. Если при вызове данной функции (start_link) имя не определено, то gen_server не будет зарегистрирован.
Module – это имя callback-модуля. Args – произвольный терм, передающийся в качестве параметра при вызове функции Module:init/1.
Если определена опция {timeout,Time}, то на инициализацию сервера отводится Time миллисекунд, по истечении которых работа сервера будет прекращена, а функция вернёт {error,timeout}. Если определена опция {debug,Dbgs}, то для каждого элемента в Dbgs будет вызвана соответствующая функция модуля sys. Подробнее смотрите описание модуля sys(3). Если определена опция {spawn_opt,SOpts}, то Sopts будет передан в качестве списка опций (spawn_opt) при вызове соответствующей BIF, которая будет использована для порождения (spawn) процесса gen_server. Подробнее смотрите описание модуля erlang (3).
Если gen_server успешно создан и проинициализирован, то функция вернёт {ok,Pid}, где Pid является идентификатором процесса gen_server. Если выполнение функции Module:init/1 завершается неудачно и причина ошибки (Reason) определена, то функция вернёт {error,Reason}. Если функция Module:init/1 возвращает {stop,Reason} или ignore, то процесс будет завершён и функция вернёт {error,Reason} или ignore соответственно. start(Module, Args, Options) -> Result
start(ServerName, Module, Args, Options) -> Result
Типы: ServerName = {local,Name} | {global,GlobalName}
Name = atom()
GlobalName = term()
Module = atom()
Args = term()
Options = [Option]
Option = {debug,Dbgs} | {timeout,Time} | {spawn_opt,SOpts}
Dbgs = [Dbg]
Dbg = trace | log | statistics | {log_to_file,FileName} | {install,{Func,FuncState}}
SOpts = [term()]
Result = {ok,Pid} | ignore | {error,Error}
Pid = pid()
Error = {already_started,Pid} | term()
call(ServerRef, Request) -> Reply
call(ServerRef, Request, Timeout) -> Reply
Типы: ServerRef = Name | {Name,Node} | {global,GlobalName} | pid() Node = atom() GlobalName = term()Request = term()Timeout = int()>0 | infinityReply = term()
- Идентификатор процесса, pid Name, если gen_server зарегистрирован локально *{Name,Node}, если gen_server зарегистрирован локально на другом узле(Node) *{global,GlobalName}, если gen_server зарегистрирован глобально. *клиент присоединён к gen_server и *клиент намерен завершить работу(is trapping exits) и *gen_server завершает свою работу в процессе обработки запроса,
multi_call(Name, Request) -> Result
multi_call(Nodes, Name, Request) -> Result
multi_call(Nodes, Name, Request, Timeout) -> Result
Типы: Nodes = [Node]
Node = atom()
Name = atom()
Request = term()
Timeout = int()>=0 | infinity
Result = {Replies,BadNodes}
Replies = [{Node,Reply}]
Reply = term()
BadNodes = [Node]
cast(ServerRef, Request) -> ok
Типы: ServerRef = Name | {Name,Node} | {global,GlobalName} | pid()
Node = atom()
GlobalName = term()
Request = term()
abcast(Name, Request) -> abcast
abcast(Nodes, Name, Request) -> abcast
Типы: Nodes = [Node]
Node = atom()
Name = atom()
Request = term()
reply(Client, Reply) -> true
Типы: Client – см. ниже
Reply = term()
enter_loop(Module, Options, State)
enter_loop(Module, Options, State, ServerName)
enter_loop(Module, Options, State, Timeout)
enter_loop(Module, Options, State, ServerName, Timeout)
Типы: Module = atom()
Options = [Option]
Option = {debug,Dbgs}
Dbgs = [Dbg]
Dbg = trace | log | statistics
| {log_to_file,FileName} | {install,{Func,FuncState}}
State = term()
ServerName = {local,Name} | {global,GlobalName}
Name = atom()
GlobalName = term()
Timeout = int() | infinity
Экспортируемые функции Module:init(Args) -> Result
Типы: Args = term()
Result = {ok,State} | {ok,State,Timeout}
| {stop,Reason} | ignore
State = term()
Timeout = int()>=0 | infinity
Reason = term()
Module:handle_call(Request, From, State) -> Result
Типы: Request = term()
From = {pid(),Tag}
State = term()
Result = {reply,Reply,NewState} | {reply,Reply,NewState,Timeout}
| {noreply,NewState} | {noreply,NewState,Timeout}
| {stop,Reason,Reply,NewState} | {stop,Reason,NewState}
Reply = term()
NewState = term()
Timeout = int()>=0 | infinity
Reason = term()
Module:handle_cast(Request, State) -> Result
Типы: Request = term()
State = term()
Result = {noreply,NewState} | {noreply,NewState,Timeout}
| {stop,Reason,NewState}
NewState = term()
Timeout = int()>=0 | infinity
Reason = term()
Module:handle_info(Info, State) -> Result
Типы: Info = timeout | term()
State = term()
Result = {noreply,NewState} | {noreply,NewState,Timeout}
| {stop,Reason,NewState}
NewState = term()
Timeout = int()>=0 | infinity
Reason = normal | term()
Module:terminate(Reason, State)
Типы: Reason = normal | shutdown | term()
State = term()
- gen_server has been set to trap exit signals (у процесса gen_serer должен быть установлен флаг обработки сигнала exit) и *стратегия завершения работы определена в спецификации потомков данного супервизора как целочисленное значение таймаута, а не как brutal_kill.
Module:code_change(OldVsn, State, Extra) -> {ok, NewState}
Типы: OldVsn = Vsn | {down, Vsn}
Vsn = term()
State = NewState = term()
Extra = term()

