Advertisement
Guest User

Untitled

a guest
Jun 22nd, 2017
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Erlang 6.72 KB | None | 0 0
  1. -module(fsmA). % Логика обработки заявок в системе А
  2. -export([timeout/2, action/4, state/4]).
  3.  
  4. % Структура data, задающая полное состояние обработчика заявки в системе А.
  5. % (не включает формальное состояния КА).
  6. % Здесь хранится число попытко опроса и ответы от систем B и C
  7. -record(data, {id, retries_B, retries_C, retries_D1, retries_D2, retries_END,
  8.            reply_B, reply_C, reply_D, reply_END}).
  9.  
  10. % Параметры работы обработчика заявок системы А.
  11. -define(TIMEOUT_B, 1*1000).
  12. -define(TIMEOUT_C, 1*1000).   %
  13. -define(TIMEOUT_D1, 1*1000).   %
  14. -define(TIMEOUT_D2, 2*1000).   %
  15. -define(TIMEOUT_END, 1*1000). %
  16.  
  17. -define(RETRIES_B, 8). % таймаут ответа от B
  18. -define(RETRIES_C, 8). % таймаут ответа от B
  19. -define(RETRIES_D1, 4). % таймаут ответа от C
  20. -define(RETRIES_D2, 4).
  21. -define(RETRIES_END, 8). % таймаут ответа от D
  22.  
  23. %
  24. % Описание автомата
  25. %
  26. % Функция state может возвращать либо только очередное состояние, либо
  27. % пару из названия состояния и изменённого полного состояния.
  28. % Например, выражение Data#data{reply_C = Answer} создаёт из структуры
  29. % Data типа data новую структуру, где будет измемено поле reply_C.
  30. % Функция action так же может вернуть либо просто ok/finish, либо пару
  31. % из них и нового состояния заявки.
  32. % Таймауты
  33. %
  34. % Пока ещё нет ни одного ответа, запустить два таймера.
  35. % Если один из них запущен, то он не будет измёнен.
  36. timeout(wait, _) ->
  37.     [{?TIMEOUT_B, timeout_B}];
  38. % Пока ещё нет ответа от А. Если таймер timeout_B
  39. % запущен, он не будет изменён.
  40. timeout(wait_B, _) ->
  41.     [{?TIMEOUT_C, timeout_C}];
  42. % Пока ещё нет ответа от B. Если таймер timeout_C
  43. % запущен, он не будет изменён.
  44. timeout(wait_C, _) ->
  45.     [{?TIMEOUT_D1, timeout_D1}];
  46. timeout(wait_D,_) ->
  47.     [{?TIMEOUT_D2, timeout_D2}];
  48. timeout(wait_END, _) ->
  49.     [{?TIMEOUT_END, timeout_END}];
  50. % В иных случаях все таймеры останавливаются.
  51. timeout(_, _) -> [].
  52.  
  53. % Функция перехода.
  54. %
  55. % Переход из начального состояния в состояние ожидания ответов.
  56. state(init, start, _, _) ->
  57.     wait;
  58.  
  59. % Приход ответа от системы B. Нам интересен этот ответ в двух возможных состояниях.
  60. state(wait, ack_B, Data, Answer) ->
  61.     {wait_B, Data#data{reply_B = Answer}};
  62. % Приход ответа от системы С.
  63. state(wait_B, ack_C, Data, Answer) ->
  64.     {wait_C, Data#data{reply_C = Answer}};
  65. % Приход ответа от системы D
  66. state(wait, nack_B, Data, Answer) ->
  67.     {wait_C, Data#data{reply_B = Answer}};
  68. state(wait_B, nack_C, Data, Answer) ->
  69.     {wait_D, Data#data{reply_C = Answer}};
  70. state(wait_D, ack_D, Data, Answer) ->
  71.     {wait_END, Data#data{reply_D = Answer}};
  72.  
  73.  
  74.  
  75. % Повторы попыток опроса системы B.
  76. state(wait, timeout_B, #data{retries_B = N}, _) when (N < ?RETRIES_B) ->
  77.     wait;
  78. state(wait, timeout_B, _, _)  ->
  79.     wait_C;
  80.  
  81. state(wait_B, timeout_C, #data{retries_C = N}, _) when (N < ?RETRIES_C) ->
  82.     wait_B;
  83. state(wait, timeout_C, _, _)  ->
  84.     wait_C;
  85.  
  86. state(wait_C, timeout_D1, #data{retries_D1 = N}, _) when (N < ?RETRIES_C) ->
  87.     wait_C;
  88. state(wait_C, timeout_D1, _, _)  ->
  89.     cancel;
  90.  
  91. state(wait_D, timeout_D2, #data{retries_D2 = N}, _) when (N < ?RETRIES_C) ->
  92.     wait_D;
  93. state(wait_D, timeout_D2, _, _)  ->
  94.     wait_END;
  95.  
  96. state(wait_END, timeout_END, #data{retries_END = N}, _) when (N < ?RETRIES_C) ->
  97.     wait_END;
  98. state(wait_END, timeout_END, _, _)  ->
  99.     cancel;
  100.  
  101. % Для остальных случаев функция перехода не определена,
  102. % автомат никуда не двигается.
  103. state(State, Message, Data, _) ->
  104.     io:format("~s: state [~w]: ignoring message [~w]~n",
  105.         [Data#data.id, State, Message]),
  106.     undefined.
  107.  
  108. % Действия при изменении состояния (выход).
  109. % Его опиcание связывается с новым состоянием,
  110. % а не исходным -- здесь это удобнее.
  111. %
  112. % Инициализация состояния.
  113. action(init, _, {Id}, _) ->
  114.     io:format("~s: started~n",
  115.         [Id]),
  116.     {ok, #data{id = Id, retries_B = 0, retries_C = 0,
  117.                     reply_B = undefined, reply_C = undefined}};
  118.  
  119. % При первом входе в состояние ожидания
  120. % опрашиваются обе системы.
  121. action(wait, start, Data, _) ->
  122.     io:format("~s: poll B & C~n", [Data#data.id]),
  123.     % Посылаем сообщения.
  124.     system_B ! {self(), request},
  125.     system_C ! {self(), request},
  126.     {ok , Data#data{retries_B = 1, retries_C = 1}};
  127.     %~ {ok, Data#data{retries = N}};
  128.  
  129. % Таймаут опроса системы B.
  130. action(wait, timeout_B, Data, _) ->
  131.     N = Data#data.retries_B + 1,
  132.     io:format("~s: poll B, ~w~n", [Data#data.id, N]),
  133.     system_B ! {self(), request},
  134.     {ok, Data#data{retries_B = N}};
  135. action(wait_B, timeout_B, Data, _) ->
  136.     N = Data#data.retries_B + 1,
  137.     io:format("~s: poll B, ~w~n", [Data#data.id, N]),
  138.     system_B ! {self(), request},
  139.     {ok, Data#data{retries_B = N}};
  140.  
  141. % Таймаут опроса системы С.
  142. action(wait, timeout_C, Data, _) ->
  143.     N = Data#data.retries_C + 1,
  144.     io:format("~s: poll C, ~w~n", [Data#data.id, N]),
  145.     system_C ! {self(), request},
  146.     {ok, Data#data{retries_C = N}};
  147. action(wait_C, timeout_C, Data, _) ->
  148.     N = Data#data.retries_C + 1,
  149.     io:format("~s: poll C, ~w~n", [Data#data.id, N]),
  150.     system_C ! {self(), request},
  151.     {ok, Data#data{retries_C = N}};
  152.  
  153. % Завершение работы
  154. action(cancel, _, Data, _) ->
  155.     io:format("~s: canceling~n", [Data#data.id]),
  156.     finish;
  157. action(done, _, Data, _) ->
  158.     io:format("~s: success, answers: ~s, ~s~n", [Data#data.id,
  159.         Data#data.reply_B, Data#data.reply_C]),
  160.     finish;
  161.  
  162. % Ничего не делать в остальных случаях
  163. action(State, _, Data, _) ->
  164.     io:format("~s: no action in [~w]~n", [Data#data.id, State]),
  165.     ok.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement