Advertisement
Guest User

Untitled

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