主要是出于教育目的,我正在尝试编写一个任务(任务是一个open_port({spawn_executable,Command}))调度程序。
我最终得到了像
这样的树 supervisor
| |
scheduler receiver
gen_event gen_event
|
supervisor
|
dispatcher
gen_server
|
supervisor
| | |
task1 ... taskN
换句话说:
底层主管根据请求启动任务,并确保在出现错误时重新启动任务
在任何时候,调度程序都准备接受带有时间戳的任务,该任务应该在
执行问题是:
提前致谢。
P上。 S. IMO,一方面,结构太复杂;另一方面,这样的结构允许我将其任何块分布(例如,许多调度器到一个接收器,一个调度器到多个接收器,许多调度器到多个接收器,每个接收器有许多调度器,甚至每个调度器的许多底层监控器) - 每一层都有自己的监督政策)。复杂性和可扩展性之间的平衡点在哪里?
答案 0 :(得分:1)
我建议更简化你的设计:
supervisor
| |
dispatcher |
+scheduler |
|
supervisor
| | |
task1 ... taskN
单独的调度程序将事件发送给启动任务等的调度程序,即使根据分发情况,也没有太大的收获。
调度程序调度程序可能很简单地在定时器模块的帮助下完成,并且可以是gen_server。 Timer可以发送可以在handle_info回调中处理的消息,也可以调用gen_server的api函数。
您还可以使用超时功能在下一个间隔之后唤醒gen_server,这会更加简单,因为您在添加新“任务”时不必担心取消计时器。
然后,调度程序/调度程序调用{{1}}来添加工作任务。
可以轻松添加分发:调度程序/调度程序可以位于与第二级主管不同的节点上。任务启动功能可以进一步分发,也可以使用pool模块进行负载均衡。
回答你的五个问题:
我怀疑你在不需要的地方使用gen_event,但由于不需要模块本身,因此可以通过删除它们来轻松修复。 gen_event是指如果您希望能够在一个事件源上注册多个处理程序,那么您将以1:1的比例使用它。监督树通常建立在主管是其他主管的直接子女的基础上。
是的,它过于复杂,看起来有点像你用OO语言做的那样,表现力较弱。只是为了准备一个可能的分发它没有必要。像Erlang这样的函数式语言中的重构比你想象的要容易得多。因此,如果您确定需要,请启动简单和拆分功能。
3 + 4。看到我完全不同的建议。
即使我使用简单的结构,也有很多灵活性(由Erlang带给你),因为如果你想拥有多个调度程序,你可以使用rpc来调用主管。您可以使用pool自动加载平衡任务分配。并且调度程序部分可以很容易地与调度程序分开(然后在顶层管理程序下),您可以将更多的公共状态与调度程序分开。