как перенести gen_server / gen_fsm с узла на узел

Я хотел бы знать, каков предложенный способ (если таковой имеется) для перемещения gen_server / gen_fsm с узла A Erlang на узел B Erlang с сохранением его внутреннего состояния.


person user601836    schedule 06.03.2012    source источник


Ответы (1)


AFAIK нет способа передать процесс между узлами erlang, и я могу подумать о многих причинах, чтобы запретить это, между другими вы можете испортить внутреннюю память узлов, просто рассмотрите процесс, который хранит данные (кроме внутреннего цикла `` Состояние '' параметр) в словаре процесса (куча процесса), двоичный (другой метод сборки мусора).

Одним из обходных путей может быть предоставление gen_fsm / gen_server метода, который может порождать новый процесс, одновременно воссоздающий внутреннее состояние сервера / конечного автомата. Я думаю, что сложнее сказать, что для реализации можно было бы просто использовать две стартовые функции:

  • тот, который инициализирует поведение (как я думаю, вы делаете прямо сейчас)
  • тот, который также принимает узел и запускается через удаленный метод, вызывает сервер на этом узле и инициализирует состояние (с помощью функции init / 1 или явным образом путем отправки сообщения, то есть состояния сервера)

Но должен сказать, что вижу здесь две основные проблемы:

  • Синхронизация: нужно убедиться, что процесс: запустить сервер на удаленном узле -> установить состояние удаленного сервера -> убить текущий локальный сервер является атомарным
  • Когерентность: другие процессы, относящиеся к локальному, должны переключить свою ссылку на удаленный

Первый может быть решен разными способами (мои два цента: явная передача сообщений между локальным и удаленным сервером - накладные расходы, но пуленепробиваемые, учитывая систему времени выполнения Erlang), последнее может быть разрешено с помощью монитора / ссылок и выходных возвращаемых значений (идентификатор удаленного сервера) или более элегантным способом с моделью публикации / подписки с процессом gen_event.

Я надеюсь, что вы найдете это полезным для решения вашей проблемы и спросите что-нибудь, если вам нужно!

person Vincenzo Maggio    schedule 06.03.2012
comment
Привет, спасибо за ответ. На самом деле мне просто нужно переместить gen_fsm на другой узел, сохраняя его состояние. Он также должен удалить себя из супервизора узла A и добавить себя в супервизор на узле B. Это доставляет мне некоторые проблемы, поскольку в течение очень короткого времени он не будет контролироваться, я думаю ... - person user601836; 06.03.2012
comment
Какова ваша стратегия руководителя? Если это один на один, вы можете без проблем удалять и добавлять процессы в дерево. Что касается задержки, в которой процессы не контролируются, это то, что я называю выше «атомарной» операцией. У вас может быть процедура, которая прослушивает оба процесса и убивает локальный тогда и только тогда, когда процесс миграции завершился успешно, но вы должны учитывать возможные изменения состояния (которые вы должны обязательно соблюдать !!!). - person Vincenzo Maggio; 06.03.2012
comment
1) да, один на один 2) самое простое решение, которое я могу придумать, - это то, в котором новый порожденный gen_fsm отправит вызов исходному после регистрации в супервизоре. Вызов вызовет нормальный выход первого экземпляра - person user601836; 06.03.2012
comment
Только если вы делаете это синхронно, то есть с серией отправки / получения на локальном сервере, чтобы гарантировать атомарность всех операций (запуск удаленного сервера, выравнивание состояния, регистрация удаленного сервера / выравнивание ссылки на глобальное имя, выход из локального сервера). В противном случае вы рискуете попасть в состояние гонки, то есть изменение состояния локального сервера между началом и концом операций. - person Vincenzo Maggio; 07.03.2012