Advertisement
Guest User

Untitled

a guest
Jun 22nd, 2017
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Erlang 6.79 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_C, 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_D, 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. state(wait_D, ack_D, Data, Answer) ->
  75.     {wait_END, Data#data{reply_D = Answer}};
  76.  
  77.  
  78.  
  79. % Повторы попыток опроса системы B.
  80. state(wait, timeout_B, #data{retries_B = N}, _) when (N < ?RETRIES_B) ->
  81.     wait;
  82. state(wait, timeout_B, _, _)  ->
  83.     cancel;
  84. state(wait_B, timeout_B, #data{retries_B = N}, _) when (N < ?RETRIES_B) ->
  85.     wait_B;
  86. state(wait_B, timeout_B, _, _)  ->
  87.     cancel;
  88.  
  89. % Повторы попыток опроса системы C.
  90. state(wait, timeout_C, #data{retries_C = N}, _) when (N < ?RETRIES_C) ->
  91.     wait;
  92. state(wait, timeout_C, _, _)  ->
  93.     cancel;
  94. state(wait_C, timeout_C, #data{retries_C = N}, _) when (N < ?RETRIES_C) ->
  95.     wait_C;
  96. state(wait_C, timeout_C, _, _)  ->
  97.     cancel;
  98.  
  99. % Для остальных случаев функция перехода не определена,
  100. % автомат никуда не двигается.
  101. state(State, Message, Data, _) ->
  102.     io:format("~s: state [~w]: ignoring message [~w]~n",
  103.         [Data#data.id, State, Message]),
  104.     undefined.
  105.  
  106. % Действия при изменении состояния (выход).
  107. % Его опиcание связывается с новым состоянием,
  108. % а не исходным -- здесь это удобнее.
  109. %
  110. % Инициализация состояния.
  111. action(init, _, {Id}, _) ->
  112.     io:format("~s: started~n",
  113.         [Id]),
  114.     {ok, #data{id = Id, retries_B = 0, retries_C = 0,
  115.                     reply_B = undefined, reply_C = undefined}};
  116.  
  117. % При первом входе в состояние ожидания
  118. % опрашиваются обе системы.
  119. action(wait, start, Data, _) ->
  120.     io:format("~s: poll B & C~n", [Data#data.id]),
  121.     % Посылаем сообщения.
  122.     system_B ! {self(), request},
  123.     system_C ! {self(), request},
  124.     {ok , Data#data{retries_B = 1, retries_C = 1}};
  125.     %~ {ok, Data#data{retries = N}};
  126.  
  127. % Таймаут опроса системы B.
  128. action(wait, timeout_B, Data, _) ->
  129.     N = Data#data.retries_B + 1,
  130.     io:format("~s: poll B, ~w~n", [Data#data.id, N]),
  131.     system_B ! {self(), request},
  132.     {ok, Data#data{retries_B = N}};
  133. action(wait_B, timeout_B, Data, _) ->
  134.     N = Data#data.retries_B + 1,
  135.     io:format("~s: poll B, ~w~n", [Data#data.id, N]),
  136.     system_B ! {self(), request},
  137.     {ok, Data#data{retries_B = N}};
  138.  
  139. % Таймаут опроса системы С.
  140. action(wait, timeout_C, Data, _) ->
  141.     N = Data#data.retries_C + 1,
  142.     io:format("~s: poll C, ~w~n", [Data#data.id, N]),
  143.     system_C ! {self(), request},
  144.     {ok, Data#data{retries_C = N}};
  145. action(wait_C, timeout_C, Data, _) ->
  146.     N = Data#data.retries_C + 1,
  147.     io:format("~s: poll C, ~w~n", [Data#data.id, N]),
  148.     system_C ! {self(), request},
  149.     {ok, Data#data{retries_C = N}};
  150.  
  151. % Завершение работы
  152. action(cancel, _, Data, _) ->
  153.     io:format("~s: canceling~n", [Data#data.id]),
  154.     finish;
  155. action(done, _, Data, _) ->
  156.     io:format("~s: success, answers: ~s, ~s~n", [Data#data.id,
  157.         Data#data.reply_B, Data#data.reply_C]),
  158.     finish;
  159.  
  160. % Ничего не делать в остальных случаях
  161. action(State, _, Data, _) ->
  162.     io:format("~s: no action in [~w]~n", [Data#data.id, State]),
  163.     ok.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement