Erlang:我应该用编写任务调度程序结束什么监督树? [英] Erlang: what supervision tree should I end with writing a task scheduler?

查看:201
本文介绍了Erlang:我应该用编写任务调度程序结束什么监督树?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

主要是教育目的,我正在尝试编写一个任务(任务是一个open_port({spawn_executable,Command}))调度程序。

Mostly in educational purposes I'm trying to write a task (task is an open_port({spawn_executable, Command})) scheduler.

我最终结束树,如

        supervisor
        |        |
scheduler        receiver
gen_event        gen_event
                     |
                supervisor
                     |
                dispatcher
                gen_server
                     |
                supervisor
                |    |   |
             task1  ... taskN

换句话说:


  1. 顶级主管启动调度程序和接收方,并确保他们将存活

  2. 接收者启动中间主管

  3. 中间主管启动调度员并确保它将存活

  4. dispatcher启动底层主管

  5. 底层主管根据请求启动任务,确保在错误

  1. top supervisor starts scheduler and receiver and makes sure they will be alive
  2. receiver starts middle supervisor
  3. middle supervisor starts dispatcher and makes sure it will be alive
  4. dispatcher starts bottom supervisor
  5. bottom supervisor starts tasks upon request and makes sure they are restarted in case of error

重新启动时,调度程序随时可以接受具有时间戳的任务,应在

at any time scheduler is ready to accept a task with a timestamp it should be executed at

问题是:


  1. 我正在使用行为吗?

  2. 结构不是太复杂了吗? (但是,将来系统将会分配)。

  3. 有没有办法将接收机+中间主管和调度员+底层主管组合在两个模块中,而不是四个实现4个行为同一时间?还有一种方法可以将Receiver + Dispatcher +底层管理员组合在一个模块中,无需中间主管,同时实现gen_event + gen_server +管理员的行为。

  4. 我以OO语言错误地将行为视为界面或多重继承行为? (这让我提出问题3和4。)

  1. Am I using behaviours right?
  2. Isn't the structure too complicated? (However, in future the system is going to become distributed.)
  3. Is there a way to combine receiver+middle supervisor and dispatcher+bottom supervisor in two modules instead of four implementing 4 behaviours in the same time?
  4. Or is there a way to combine receiver+dispatcher+bottom supervisor in one module, eliminating the need for middle supervisor, implementing gen_event+gen_server+supervisor behaviour at the same time?
  5. Am I mistaken thinking of behaviours as of interfaces or multi-inheritance in OO languages? (That makes me ask questions 3 and 4.)

提前感谢。

P。海事组织一方面,结构太复杂;另一方面,这样的结构让我可以分散其任何块(例如,许多调度器到一个接收器,一个调度器到许多接收器,许多调度器到许多接收器,每个接收器的许多调度器,甚至每个调度器的许多底层监督器 - 每层都有自己的监督政策)。复杂性与可扩展性之间的平衡点在哪里?

P. S. IMO, on one hand, the structure is too complicated; on the other hand such a structure lets me make any of its blocks distributed (for example, many schedulers to one receiver, one scheduler to many receivers, many schedulers to many receivers, many dispatchers for each receiver and even many bottom supervisors for each dispatcher - every layer with is own supervision policy). Where is the balance point between complexity and extensibility?

推荐答案

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

What I would suggest is simplifying your design much more like:

        supervisor
        |        |
 dispatcher      |
 +scheduler      |
                 |
            supervisor
            |    |   |
         task1  ... taskN

有一个单独的调度程序发送没有太多的收益事件发送到启动任务的调度程序。甚至在分发的情况下。

The there is not much gain from having a separate scheduler sending events to a dispatcher which starts tasks etc. Even in the light of distribution.

调度程序调度程序可能很简单地通过定时器模块的帮助完成,并且可以成为gen_server。 Timer可以发送可以在handle_info回调中处理的消息,也可以调用gen_server的api函数。

The dispatcher-scheduler can be probably quite simply done with the help of the timer module and can be a gen_server. Timer can either send messages which you can process in the handle_info callback or call api functions of your gen_server.

您还可以使用超时功能在gen_server之后唤醒gen_server下一个时间间隔会更简单,因为您不必担心在添加新的任务时取消定时器。

You could also use the timeout functionality to wake up the gen_server after the next interval that would be even simpler since you don't have to worry abou canceling timers when you add a new "task".

调度程序/调度程序然后调用 supervisor:start_child 添加工作任务。

The dispatcher/scheduler then calls supervisor:start_child to add working tasks.

分发可以轻松添加:dispatcher / scheduler可以在单独的节点上二级主管。任务启动功能可以进一步分发,也可以使用模块进行负载平衡。

Distribution can be added easily: dispatcher/scheduler can be on a separate node than the second level supervisor. The tasks starting function can distribute further and maybe using the pool module for load balancing.

回答你的五个问题:


  1. 我怀疑你是使用gen_event不需要它,但是由于模块本身不需要,因此通过删除它们很容易修复。 gen_event是如果你想能够在一个事件源上注册许多处理程序,你使用它1:1。监督树通常是与其他主管的直接孩子一起建立的。

  1. I suspect you are using gen_event where it is not needed, but since the modules itself are not needed its easily fixed by removing them. gen_event is if you want to be able to register many handlers on one event source, you are using it 1:1. Supervision trees are usually built with supervisors being the direct child of other supervisors.

是的,它太复杂了,看起来有点像你会用OO语言表现力较弱。只是为了准备一个可能的分配,它不是必需的。像Erlang这样的功能语言中的重构比你想象的容易得多。如果您需要,请启动简单和分割功能。

Yes its too complicated, looks a bit like you would do it in OO languages with less expressive power. And just to prepare for a maybe distribution its not necessary. Refactoring in a functional language like Erlang is much easier than you probably think. So start simple and split functionality if you see the need.

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

3+4. See my altogether different suggestion.


  1. 它不是OO喜欢的。 OTP中的行为只是在通用模块中隐藏过程机制的回调模块。

即使有简单的结构,我建议有很多灵活性(由Erlang带给您),因为如果您想要有多个调度程序,您可以使用rpc调用主管。您可以使用自动平衡任务分配。调度程序部分可以轻松地从调度程序中分离出来(两者都在上级管理员之下),您可以将更多的公共状态与调度程序分开。

Even with the simple structure I suggested there is plenty of flexibility (brought to you by Erlang) because if you want to have multiple schedulers you can just use rpc to call the supervisor. You can use pool to automatically load balance distribution of tasks. And the dispatcher part can be easily separated from the scheduler (both under the toplevel supervisor then) the you can have more common state separated from the scheduler.

这篇关于Erlang:我应该用编写任务调度程序结束什么监督树?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆