Erlang:我应该以编写任务调度器来结束什么监督树?

Erlang:我应该以编写任务调度器来结束什么监督树?,erlang,task,behavior,scheduler,erlang-supervisor,Erlang,Task,Behavior,Scheduler,Erlang Supervisor,主要出于教育目的,我正在尝试编写一个任务(任务是一个开放的_端口({spawn_executable,Command}))调度器 我的结局就像那棵树一样 supervisor | | scheduler receiver gen_event gen_event | supervisor |

主要出于教育目的,我正在尝试编写一个任务(任务是一个开放的_端口({spawn_executable,Command}))调度器

我的结局就像那棵树一样

        supervisor
        |        |
scheduler        receiver
gen_event        gen_event
                     |
                supervisor
                     |
                dispatcher
                gen_server
                     |
                supervisor
                |    |   |
             task1  ... taskN
换言之:

  • 最高主管启动调度程序和接收器,并确保它们处于活动状态
  • 接受者启动中层主管
  • 中间主管启动dispatcher并确保它处于活动状态
  • 调度员启动底层主管
  • 底层主管根据请求启动任务,并确保在出现错误时重新启动任务

  • 调度程序随时准备接受带有时间戳的任务,该任务应在该时间执行

  • 当满足时间戳时,它会通知某些事件管理器
  • 然后,同一事件管理器通知接收方,并通过中间主管将消息传递给调度程序
  • dispatcher有一些业务逻辑,这就是为什么它不是无状态的,例如,某些类型的任务不能同时执行
  • 当所有条件都满足时,调度员将任务传递给底层主管,以确保任务得到执行,直到获得正常退出或绕过部分转售
  • 底部主管返回一条消息,然后将该消息传递给某个事件管理器
  • 调度器最终接收到该消息,从其队列中删除任务,或者重新将其排队,或者执行其他操作
  • 问题是:

  • 我使用行为学对吗
  • 结构不是太复杂了吗?(然而,未来该系统将成为分布式系统。)
  • 是否有一种方法可以将接收器+中层主管和调度器+底层主管组合在两个模块中,而不是四个同时执行4种行为
  • 或者有没有一种方法可以将接收器+调度器+底层主管组合在一个模块中,从而消除对中间主管的需求,同时实现gen_事件+gen_服务器+主管行为
  • 我是否将行为误认为是面向对象语言中的接口或多重继承?(这让我提出了问题3和4。)
  • 提前谢谢


    一方面,结构过于复杂;另一方面,这种结构允许我将其任何块分布(例如,多个调度器分配给一个接收器,一个调度器分配给多个接收器,多个调度器分配给多个接收器,每个接收器分配给多个调度器,甚至每个调度器分配给多个底层管理器-每一层都有自己的管理策略)。复杂性和可扩展性之间的平衡点在哪里

    我的建议是简化您的设计,更像:

            supervisor
            |        |
     dispatcher      |
     +scheduler      |
                     |
                supervisor
                |    |   |
             task1  ... taskN
    
    如果有一个单独的调度器将事件发送给一个启动任务的调度器,那么即使是根据分布情况,也不会有太大的好处

    调度器调度器可以非常简单地在计时器模块的帮助下完成,并且可以是gen_服务器。计时器可以发送您可以在handle_info回调中处理的消息,也可以调用gen_服务器的api函数

    您还可以使用超时功能在下一个间隔后唤醒gen_服务器,这将更加简单,因为您不必担心在添加新“任务”时取消计时器

    然后,调度器/调度器调用
    supervisor:start\u child
    添加工作任务

    可以轻松添加分发:调度器/调度器可以位于与二级主管不同的单独节点上。任务启动功能可以进一步分配,也可以使用模块进行负载平衡

    要回答您的五个问题:

  • 我怀疑您在不需要gen_事件的地方使用了它,但由于不需要模块本身,因此可以通过移除它们来轻松修复。gen_事件是指,如果您希望能够在一个事件源上注册多个处理程序,则可以1:1使用它。监督树通常是建立在监督者是其他监督者的直接子女的基础上的

  • 是的,它太复杂了,看起来有点像用表达能力较弱的OO语言。只是为了准备一个可能的分发,这是没有必要的。用Erlang这样的函数式语言进行重构比您想象的要容易得多。因此,如果您认为需要,请启动简单和拆分功能

  • 3+4。看看我完全不同的建议

  • 这可不象。OTP中的行为只是将流程机制隐藏在通用模块中的回调模块

  • 即使使用我建议的简单结构,也有很大的灵活性(Erlang为您带来的),因为如果您想要有多个调度器,您可以使用rpc调用管理器。您可以使用自动平衡任务的负载分布。调度器部分可以很容易地从调度器中分离出来(都在顶级主管的领导下),您可以从调度器中分离出更多的公共状态。

    我的建议是简化您的设计,更像:

            supervisor
            |        |
     dispatcher      |
     +scheduler      |
                     |
                supervisor
                |    |   |
             task1  ... taskN
    
    如果有一个单独的调度器将事件发送给一个启动任务的调度器,那么即使是根据分布情况,也不会有太大的好处

    调度器调度器可以非常简单地在计时器模块的帮助下完成,并且可以是gen_服务器。计时器可以发送您可以在handle_info回调中处理的消息,也可以调用gen_服务器的api函数

    您还可以使用超时功能在下一个间隔后唤醒gen_服务器,这将更加简单,因为您不必担心在添加新“任务”时取消计时器

    然后,调度器/调度器调用
    supervisor:start\u child
    添加工作任务

    可以轻松添加分发:调度器/调度器可以位于与二级主管不同的单独节点上。任务启动功能可以进一步分配,并可能使用模块进行负载平衡