Normally, I would solve this via something like the following:
task = _taskProvider.getNextFromQueue();
if (task.id == TaskExecutor.TasksEnum.One) {
_taskExecutor.executeTaskOne();
return;
} else if (task.id == TaskExecutor.TasksEnum.Two) {
_taskExecutor.executeTaskTwo();
return;
} else if (task.id == TaskExecutor.TasksEnum.Three) {
_taskExecutor.executeTaskThree();
return;
}
//and so on...
I could switch if-else
to switch
if needed.
I do believe there exists a better way to implement similar code.
One thing that comes to mind is to use a table (map) to store task ids and pointers to corresponding functions, but I am not sure if it's useful and provide adequate performance.
Another thing that concerns me is notification mechanism. This problem occurs when TaskProvider
and TaskExecutor
are two separate entities that operate on different threads. It becomes even worse if several actions take some time to finish execution and I need to create a logic to make a caller wait for the result.
For example, if executeTaskTwo()
takes some time to complete, I would execute it in a background thread, meaning executeTaskTwo()
would return nearly immediately, while the task itself would still be executing. But how do I notify the caller about it's completion once it's over?
I guess that the solution involves heavy modification, maybe some event libraries (I've never worked with these before). I need a starting point. I guess there exist a patterns of some sort, but I do not know which one exactly.
Update 1:
Some more info about general architecture and problems There are three entities:
Hardware
- manages hardware signals (inputs, outputs). Cares only about hardware, does not ask questions about why?Network
- manages remote connections to the device. Cares only about data transmission. Again, it does not care about what the data represents.Controller
- controls the actual device's task/algorithm (what this device does). This is the brain of the device.
Each entity operates on it's own thread. Sometimes, an event happen and one entity needs to send this event to the other entity (or all of them). For example, a command from network
turns on some LED that is managed by hardware, or, a failure to turn this LED should be signaled to both network
(notify remote clients) and controller
(execute emergency stop).
Right now each entity (class) has a set of function (methods) that other entities call when they this entity to do something. If a called function takes time to execute, a caller entity is blocked, which is bad. Spawning background thread to handle each command (or event) also feels wrong.
Right now each entity has it's own queue of commands and executes it's commands sequentially (execute(queue.getNext())
), but it is ineffective because some commands are fast to execute and others take time and resources.