Персональные инструменты
Вы здесь: Главная Блог Erlang/OTP Finite State Machine behaviour

Erlang/OTP Finite State Machine behaviour

Автор: Фёдор Сахаров at 2009-11-28 22:10 |

Одним из паттернов поведений приложений в платформе OTP является паттерн поведения детерминированного конечного автомата (gen_fsm). Как и в случае с паттерном поведения сервера (gen_server), необходимо реализовать модуль, содержащий обратные вызовы. Среди обратных вызовов можно выделить init, terminate, которые вызываются во время инициализации и завершения процесса соответственно и функции имеющие вид StateName(Event, StateData). Последний тип функций описывает состояние автомата с именем StateName. В модуле должно присутствовать по одной функции такого вида на каждое состояние. Рассмотрим пример приложения, имеющего 4 состояния.

 

-module(testotp_fsm).
-behaviour(gen_fsm).
-export([init/1,beg_state/2,
        mid_state1/2,mid_state2/2,end_state/2,terminate/3]).

init(Args) ->
        {ok,beg_state,infinity}.

beg_state(go_mid_one,_) ->
        io:format("Going to middle state 1~n",[]),
        {next_state,mid_state1,"data"};

beg_state(go_mid_two,_) ->
        io:format("Going to middle state 2~n",[]),
        {next_state,mid_state2,"data"};

beg_state(_,_) ->
        io:format("Unknown event!~n",[]),
        {next_state,mid_state2,"data"}.

mid_state1(go_last,_) ->
        io:format("Going to the last state from middle state 1~n",[]),
        {next_state,end_state,"data"};

mid_state1(_,_) ->
        io:format("Unknown event!~n",[]),
        {next_state,mid_state1,"data"}.

mid_state2(go_last,_) ->
        io:format("Goint to the last state from middle state 2~n",[]),
        {next_state,end_state,"data"};

mid_state2(_,_) ->
        io:format("Unknown event!~n",[]),
        {next_state,mid_state2,"data"}.

end_state(finish,_) ->
        io:format("This is the third state~n",[]),
        {stop,normal,ok,"data"};

end_state(_,_) ->
        io:format("Unknown event!~n",[]),
        {next_state,end_state,"data"}.

terminate(_,_,_) ->
        io:format("Terminated.~n",[]).

Запустим приложение и походим между состояниями.

 

> {ok,FSMPid} = gen_fsm:start_link(testotp_fsm,any,[any]).

> gen_fsm:send_event(FSMPid,go_mid_two).

Going to middle state 2

ok

> gen_fsm:send_event(FSMPid,go_last).

Goint to the last state from middle state 2

ok

> gen_fsm:send_event(FSMPid,fin).

Unknown event!

ok

> gen_fsm:send_event(FSMPid,finish).

This is the third state

ok

Terminated.

 

That’s it! Паттерны поведений сильно упрощают код и делают его совместимым с деревьями контроля OTP. Удачи!

Действия с Документом