Перезапуск процесса erlang и сохранение состояния
У меня есть процесс супервизора, который запускает количество дочерних процессов. В настоящее время, когда ребенок умирает, я порождаю новый процесс с новым Pid. Это означает, что я теряю информацию о состоянии моего ребенка, который только что умер. Я хочу, чтобы мои клиенты общаются с дочерними процессами, используя всегда один и тот же идентификатор. Несмотря на то, что дочерний процесс может умереть и быть перезапущен супервизором.
Я думал о регистрации дочерних процессов с уникальными именами и хранение детской состояние в таблице ets. Вопрос в том, каков рекомендуемый способ подхода к такой проблеме в Эрланге?
спасибо!
3 ответов
сохранение состояния процесса в таблице ets будет работать для сохранения вашего состояния между сбоями, и я обычно использую глобальный реестр для предоставления процессов постоянные имена. (Игрок 200 будет зарегистрирован как {player, 200}.) Я не рекомендую использовать локальный реестр, потому что он требует, чтобы вы использовали атомы, и если у вас много дочерних процессов, вы можете быстро разжевывать свой предел атомов, создавая их динамически (например, player_200, player_201 и т. д.)
хранение ребенка однако состояние в таблице ets имеет свои собственные риски и проблемы. Если ребенок аварийно завершает работу между моментом возникновения ошибки и сохранением в таблице ets, вы должны быть в порядке. Однако что делать, если вы обрабатываете данные, которые заставляют ребенка сохранять состояние мусора, а затем сбой при обработке следующего сообщения? Вы перезапустите процесс, загрузите плохое состояние из таблицы ets и снова выполните сбой следующего сообщения. Конечно, есть способы справиться с этим, но вы должны знать, что это возможность и работа вокруг нее.
в то время как Erlang скрывает проблемы распределения таблицы ets для всех процессов, он делает это за счет CPU и потенциальных конфликтов. Если вы вносите много изменений в таблицу ets, вы заплатите за это в производительности.
Если ваши дети разбиваются, разве вы не должны искать способ для них, чтобы удалить ошибочные условия, в любом случае? Обычно я воспринимаю сбой процесса как то, что мне нужно, чтобы искоренить причину и исправить. ?
использование таблиц ETS, вероятно, является способом сохранить состояние. Vinoski это обсуждается, как сделать возможным перезапуск аварийного процесса при сохранении данных таблицы ETS.
поскольку @user30997 указывает, что данные в таблице могут быть причиной сбоя процесса, поэтому при перезапуске вы можете проверить таблицу (или установить ограничение на то, сколько раз процесс будет перезапущен...)
для связывания процессов с id вы следует взглянуть на gproc что отлично подходит для этого.
используйте eventsourcing, сохраняйте все события и воспроизводите их для восстановления состояния. Если вам нужны быстрые повторы, сделайте снимок. Пример ниже: https://github.com/bryanhunter/cqrs-with-erlang/tree/ndc-oslo
на самом деле, было бы неплохо построить полную структуру на основе этого примера.