2015-07-13 3 views
2

Я создаю общий сервер Erlang, который должен одновременно обрабатывать сотни клиентских подключений. Для простоты предположим, что сервер выполняет для каждого клиента некоторые базовые вычисления, например, сложение или вычитание всех двух значений, которые предоставляет клиент.Контроль доступа от одного gen_fsm к другому

В качестве отправной точки я использую this tutorial для базового взаимодействия клиент-сервер TCP. Отрывок, который представляет дерево надзора:

   +----------------+ 
       | tcp_server_app | 
       +--------+-------+ 
         | (one_for_one) 
     +----------------+---------+ 
     |       | 
+-------+------+   +-------+--------+ 
| tcp_listener |   + tcp_client_sup | 
+--------------+   +-------+--------+ 
            | (simple_one_for_one) 
          +-----|---------+ 
          +-------|--------+| 
          +--------+-------+|+ 
          | tcp_echo_fsm |+ 
          +----------------+ 

Я хотел бы расширить этот код и позволяет tcp_echo_fsm передать контроль над гнездом к одному из двух модулей: tcp_echo_addition (вычислить добавление каждых два значений клиента), или tcp_echo_subtraction (для вычисления вычитания между каждыми двумя значениями клиента).

tcp_echo_fsm будет выбирать, какой модуль для обработки сокета на основе первого сообщения от клиента, например, если клиент посылает <<start_addition>>, то было бы передать управление tcp_echo_addition.

Предыдущая схема становится:

   +----------------+ 
       | tcp_server_app | 
       +--------+-------+ 
         | (one_for_one) 
     +----------------+---------+ 
     |       | 
+-------+------+   +-------+--------+ 
| tcp_listener |   + tcp_client_sup | 
+--------------+   +-------+--------+ 
            | (simple_one_for_one) 
          +-----|---------+ 
          +-------|--------+| 
          +--------+-------+|+ 
          | tcp_echo_fsm |+ 
          +----------------+ 
            | 
            | 
       +----------------+---------+ 
     +-------+-----------+  +-------+--------------+ 
     | tcp_echo_addition |  + tcp_echo_subtraction | 
     +-------------------+  +-------+--------------+ 

Мои вопросы:

  1. Я на правильном пути? Является ли учебное пособие, которое я использую в качестве отправной точки для масштабируемого проекта TCP-сервера?

  2. Как я могу передать управление от одного gen_fsm (а именно, tcp_echo_fsm) к другому gen_fsm (либо tcp_echo_addition или tcp_echo_subtraction)? Или еще лучше: это правильный/чистый способ разработки сервера? Этот related question предполагает, что передача управления между gen_fsm и другим модулем не является тривиальной, и в этом случае может быть что-то не так.

ответ

3

Для 2, вы можете использовать gen_tcp:controlling_process/2 передать управление соединения TCP: http://erlang.org/doc/man/gen_tcp.html#controlling_process-2.

Для 1, я не уверен в значении создания нового модуля, а не для обработки логики вычитания и добавления как части определенных состояний конечного конечного автомата. Это создает код, который теперь работает за пределами вашего дерева наблюдения, поэтому сложнее обрабатывать ошибки и перезапускать. Почему бы не определить сложение и вычитание, поскольку разные состояния в ваших государственных машинах обрабатывают эту логику в этих двух состояниях?

Вы можете создать tcp_echo_fsm:subtraction_state/2,3 и tcp_echo_fsm:addition_state/2,3, чтобы обработать эту логику и использовать свое первое сообщение для перехода к соответствующему состоянию, а не добавления сложности в ваше приложение.

+0

1. Я хочу, чтобы разные gen_fsm обрабатывали сложение и вычитание, потому что я хотел бы, чтобы дизайн был расширяемым. Например, я хотел бы иметь возможность добавлять какие-либо вычисления (умножение, добавление 3 последующих чисел и т. Д.). Было бы громоздкой иметь всю эту логику в одном gen_fsm. Это мое мнение усилилось после того, как я увидел этот связанный [post] (https://stackoverflow.com/questions/10024758/change-gen-fsm-state-to-a-function-in-a-different-module). Для 2: спасибо, я посмотрю. – adizere

+0

@adizere, что имеет смысл, но отчасти трудно ответить окончательно, так как это будет зависеть от вашего конкретного приложения.Одна вещь, которую следует учитывать, - использовать gen_server 'вместо' gen_fsm ', если поведение ваших' tcp_echo_ * 'функций не зависит от состояния. Вы также должны посмотреть, что происходит в дереве наблюдения, когда вы создаете новую функцию 'tcp_echo_ *', вам нужно динамически добавить их через 'supervisor: start_child/2'. – dethtron5000

+0

Думаю, я пойду с 'gen_server' вместо' gen_fsm' и посмотрю, что произойдет. Я следую теперь [этот учебник] (http://learnyousomeerlang.com/buckets-of-sockets#sockserv-revisited). – adizere

Смежные вопросы