【问题标题】:Workflows as GenServers作为 GenServer 的工作流
【发布时间】:2018-10-28 11:12:09
【问题描述】:

所以我偶尔会涉足 Elixir,但过去我一直在努力解决的问题是如何使用流程对应用程序建模。考虑到这一点,我想彻底检查我将要做的事情,看看它是否有意义。

所以我正在构建一个简单的工作流应用程序,每个阶段都会有关于它如何流向下一个阶段的规则,它可能收集的状态以及由于状态变化而触发的事件。阶段不是线性的,并且本质上是任何流程图中的图形。

我看到流程图的第一个想法是它看起来非常像一个流程的集合。

我的想法是将流程中的每个阶段建模为自己的 GenServer,因为它们是可寻址的,可以保持状态并且可以用于执行事件。

如果这是一个明智的方法(如果不是,请告诉我)那么我有几个问题:

  • 由于这是一个图表,每个阶段可以有多个连接的下一个和上一个阶段。我希望这些阶段受到监督,现在我真的要在这里表明我缺乏理解,但我认为主管只监控与其相关的进程,而不是子进程,这是否正确?如果是这种情况,我希望每个阶段都充当 GenServer 和主管,这可能/明智吗?

  • 有没有办法获取一个进程的所有子进程?

  • 这样合理吗?

克里斯

【问题讨论】:

  • 旁注:“作为 GenServer 和主管”—Supervisor 简而言之 GenServer
  • 是的,我知道这一点我更想问是否适合将它们用作除母鹿监督之外的东西。我没有说清楚,所以还是感谢您的澄清。

标签: architecture elixir modeling


【解决方案1】:

GenServers 绝对是您可以完成此类任务的一种方式,但在采用这种方式时您必须解决一些实施问题。

因此,Elixir 已经为此提供了更高级别的实现,称为GenStage,这是一件好事。您可以创建具有多个阶段的管道,其中每个阶段都可以充当消费者、生产者或两者兼而有之。

您还可以在每个阶段生成更多子进程,或者让这些阶段自己完成工作并使用ConsumerSupervisor 来监督它们。



您还可以让多个阶段并行运行,将数据提供给其他阶段,其中大部分实现由它自动处理。


这里有一些资源:

【讨论】:

  • 嘿,谢谢,是的,我知道 GenStage,但我看到了通过流处理数据负载的主要用例。我更多地谈论的是长期存在的业务工作流程,其中少量状态通过它,即某人完成了一个表格,这进入了一个需要几个人批准并向他们发送电子邮件的阶段......等等。我看到 GenStage 更多的是处理背压和大量数据流。它适合这样的事情吗?
  • 如前所述,这完全不是我想要做的
【解决方案2】:

我认为流程树不需要与图的拓扑相同。

我会做的是每个图表只使用一个主管,这个图表中的所有进程都将由它监督。

使用Supervisor.which_children/1获取Supervisor的所有子进程。

我相信using a Supervisor as a GenServer is a bad practice

【讨论】:

    【解决方案3】:

    您可能想看看Plug(Phoenix 所基于的行为)是如何工作的。基本上,定义的每个函数(插头)都接受并返回一个结构,conn,并且插头的管道链逐渐构建/转换它/等等。

    如果我对您的理解正确,这种模式会起作用 - 您最初构建一个结构/映射,然后您只需将其传递给一组逐渐转换它的函数。您也应该能够分支,它不需要是线性的。这样状态就保留在一个地方(您需要做的就是保持该结构,您可以使用单个 genserver 来完成)。

    虽然这样做很诱人,但我会认真避免将每个步骤建模为 genserver:这是在滥用它们来尝试模拟对象。使用仅重建状态的普通函数会更简单、更容易调试且更惯用(this article 解释了何时使用进程以及何时不使用进程,以及更详细的原因)。

    【讨论】:

    • 是的,我得出了这个结论,与其说是 Plug,不如说是每个阶段都有一个 GenServer。我想我会在整个流程实例中创建一个。
    猜你喜欢
    • 2012-03-10
    • 2015-09-15
    • 1970-01-01
    • 1970-01-01
    • 2015-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    相关资源
    最近更新 更多