Mostly in educational purposes I'm trying to write a task (task is an open_port({spawn_executable, Command})) scheduler.
I end up with the tree like
supervisor
| |
scheduler receiver
gen_event gen_event
|
supervisor
|
dispatcher
gen_server
|
supervisor
| | |
task1 ... taskN
In other words:
- top supervisor starts scheduler and receiver and makes sure they will be alive
- receiver starts middle supervisor
- middle supervisor starts dispatcher and makes sure it will be alive
- dispatcher starts bottom supervisor
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
- when timestamp is met it notifies some event_manager
- receiver is then notified by the same event manager and passes the message to dispatcher through the middle supervisor
- dispatcher has some business logic that is why it is not stateless, for example, some kind of tasks cannot be executed simultaneously
- when all conditions are met dispatcher passes task to bottom supervisor which makes sure task is executed until normal exit is got or some thresold is bypassed
- bottom supervisor returns back a message which is then passed up-up-up to some event manager
- and scheduler eventually receives this message, removing task from its queue or reenqueueing it or something else
The questions are:
- Am I using behaviours right?
- Isn't the structure too complicated? (However, in future the system is going to become distributed.)
- 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?
- 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?
- Am I mistaken thinking of behaviours as of interfaces or multi-inheritance in OO languages? (That makes me ask questions 3 and 4.)
Thanks in advance.
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?