Let's consider the following estimates for capacity and bandwidth:
Based on these estimates, we can calculate the required capacity and bandwidth for the Task Scheduler system:
Considering each task data size as 1 KB and the creation of 6000 tasks per minute, the system will need a database capable of storing and managing this data efficiently. Therefore, the database should be able to handle a large volume of data insertion and retrieval operations.
CreateTask - creates a task
input: task name, code function to be executed (this could be literal code passed in or reference to some file with entry point)
output: creation success or failure, 201 https code response.
ScheduleTask - schedule the task for a specify time to run
input: date time to execute the task, name of the task to be executed
output: schedule success or failure, 201 https code response.
ExecuteTask - immediately executes the task by queuing it up.
input: task name
output: job id
RescheduleTask - reschedules the task for a different time to run.
input: job id
output: job id
ListTasks - list tasks
input: none
output: list of tasks
UpdateTask - updates a task
input: task name, code function or reference to code file
output: update success or failure
DeleteTask - deletes a task
input: task id
output: success or failure
We will design the database schema in InfluxDB for a Task Scheduler system, we can follow a structured approach incorporating the key components of InfluxDB's time-series data model.
Measurement: task_schedule
Measurement: task_metrics
Measurement: task_logs
task_schedule: Stores scheduled task information including task name, execution time, task status (pending, in progress, completed), recurrence interval, start date, and end date.
task_metrics: Contains performance metrics data related to task execution such as CPU utilization, memory utilization, disk usage, and timestamp.
task_logs: Records log messages generated during task execution with details like log message, log level, and log timestamp.
InfluxDB is purpose-built for handling time-series data, making it highly efficient for storing and querying timestamped data points. This aligns well with the nature of scheduling tasks with execution times.
Secondly, InfluxDB provides excellent write performance for ingesting time-series data rapidly. This is crucial for a Task Scheduler system where tasks may be created, updated, and executed frequently, requiring efficient data write operations.
Priority-Based Task Execution:
we can utilize Dijkstra's algorithm to assign priorities to tasks based on their dependencies, execution times, or any other criteria. Here's how Dijkstra's algorithm can be applied for task prioritization:
Some tasks with dependencies need to be executed in a specific order. Overlapping schedules can disrupt this order, causing tasks to run out of sequence and leading to incorrect results. In addition, some tasks may have different priorities based on their importance. With overlapping schedules, lower priority tasks might delay higher priority tasks if resources are allocated based on the order of arrival rather than priority.
To address overlapping task schedules we can take the following approaches:
When a new task is scheduled to run at the same time as an existing task, we can implement conflict resolution mechanisms to prioritize or reschedule tasks based on predefined rules (e.g., priority levels or task dependencies).
Higher priority task will be executed first. If there's a dependency issue then we will order the tasks using algorithm like topological sort and execute the task in that order.
The task scheduler can maintain a graph data structure where nodes represent tasks and edges represent dependencies between tasks. When a task is scheduled, the scheduler can traverse the graph to ensure all dependencies are met before executing the task.
Flow for how the task scheduler handles this scenario
Concurrency can be managed using techniques like locking mechanisms or thread pools to control access to shared resources and ensure tasks are executed safely without conflicts.
Load Balancing Strategies:
Task Checkpointing:
Task checkpointing involves saving the state of a task at specific points in its execution to enable recovery in case of failure.
Checkpointing allows the system to resume task execution from the last saved state rather than restarting the task from scratch, minimizing the impact of failures. Checkpointing can be implemented by periodically saving the task state to persistent storage (e.g., database or disk) or through in-memory snapshots.
Below is a diagram illustrating checkpointing:
Replication:
In addition to checkpointing we should also replicate task scheduler components and data across multiple servers to ensure high availability.
Finally, we can use a cloud service such as AWS to host our Task Scheduler service. AWS will cover non functional requirements such as scalability and reliability. This way we don't need to worry about consensus algorithms like Paxos or Raft. AWS abstracts these details away.
Consistency vs. Availability:
In the context of task scheduling, the system may lean towards favoring availability over strong consistency. For example, in scenarios where it is critical for tasks to be scheduled and executed without delays, ensuring that the system remains available and operational becomes a higher priority than strict consistency across all nodes.
Task Execution Failure:
A task scheduled for execution may fail due to various reasons such as exceptions, errors in the task logic, or external dependencies not being available.
System Crashes:
The Task Scheduler system itself may crash or become unresponsive due to hardware failures, software bugs, or resource exhaustion.
Network Issues:
Network failures or interruptions can disrupt communication between system components, leading to task scheduling or execution failures.
Deep dive into advanced scheduling algorithms beyond Dijkstra's algorithm, exploring real-time scheduling heuristics and adaptive strategies to cope with varying task complexities and priorities.
Extensive coverage on handling network failures, dynamic scaling strategies, and incorporating advanced fault detection and recovery mechanisms to ensure seamless operation during system disruptions.
It would be interesting to discuss more on the retry mechanism for failed tasks to automatically retry execution a certain number of times before marking the task as failed.
More discussion on logging and monitoring would contribute more to the solution.
More discussion on how to incorporate fallback logic or alternative paths for critical tasks to handle failures gracefully and ensure continuity.
Set up an alerting system to notify administrators or users when tasks fail to ensure prompt attention and resolution.
We can also consider more advanced scheduling algorithms beyond Dijkstra's algorithm by exploring real-time scheduling heuristics and adaptive strategies to cope with varying task complexities and priorities.