Рабочие процессы как GenServers - PullRequest
0 голосов
/ 18 мая 2018

Так что я иногда баловался с Elixir, но в прошлом я боролся с тем, как всегда моделировать приложение с процессами.Имея это в виду, я хочу проверить, что я собираюсь сделать, чтобы понять, имеет ли это смысл.

Итак, я создаю простое приложение рабочего процесса, у каждого этапа будут свои правила о том, как оно переходит на следующий этап (этапы), состояние, которое оно может собирать, и события, которые запускаются в результате изменения состояния.Этапы не являются линейными и, по сути, представляют собой график, как на любой диаграмме потоков.

Моя первая мысль при рассмотрении блок-схемы заключается в том, что она очень похожа на совокупность процессов.

Я должен был смоделировать каждую стадию в потоке как свой собственный GenServer, так как они адресуемы, могут содержать состояние и могут использоваться для выполнения событий.

Если это разумный подход (пустья знаю, если это не так), то у меня есть несколько вопросов:

  • Поскольку это график, каждый этап может иметь несколько связанных следующих и предыдущих этапов.Я хотел бы, чтобы эти этапы контролировались, теперь я действительно собираюсь показать свое отсутствие понимания здесь, но прав ли я, полагая, что руководитель контролирует только процессы, связанные с ним, а не дочерние процессы?Если это так, я хочу, чтобы каждая стадия выступала в роли GenServer и супервизора, возможно ли это / разумно?

  • Есть ли способ получить все дочерние процессыпроцесс?

  • Это разумно?

Крис

Ответы [ 3 ]

0 голосов
/ 18 мая 2018

Я думаю, что дерево процессов не должно иметь одинаковую топологию графика.

Я бы использовал только один супервизор для каждого графика, все процессы в этом графике будут контролироваться им..

Используйте Supervisor.which_children/1 для получения всех дочерних процессов супервизора.

И я считаю, использование супервизора в качестве GenServer - плохая практика .

0 голосов
/ 19 мая 2018

Возможно, вы захотите посмотреть, как Plug , поведение, на котором построен Phoenix, работает.По сути, каждая определенная функция (плагин) принимает и возвращает структуру, conn, и цепочка плагинов постепенно строит ее / трансформирует / т. Д.

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

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

0 голосов
/ 18 мая 2018

GenServers - это, безусловно, один из способов добиться чего-то подобного, но при этом вам придется решить несколько проблем с реализацией.

Так что хорошо, что Elixir уже предоставляет более высокий уровеньВнедрение именно для этого называется GenStage .Вы можете создавать конвейеры с несколькими этапами, где каждый этап может выступать в роли потребителя, производителя или обоих.

Вы также можете создавать дальнейшие дочерние процессы на каждом этапе, или эти этапы выполняют работу самостоятельно и используют ConsumerSupervisor , чтобы контролировать их.

Можно также выполнить несколько этапов параллельной подачи данных на другие этапы, где основная часть реализации обрабатывается им автоматически.


Вот некоторые ресурсы:

...