Implement dependency checking

For #167

- Circular dependency is only possible on UpdatingTask since task is added one by one and a task cannot dependent on non existing task.
- Hence during UpdateTask, the graph is checked for circular dependency, if it is, revert the changes and rebuild the graph again.
- When deleting task, right now the course of action is to simply rebuild the graph.

All the said operation takes O(V + E)
I just // NOLINT this lol