Hone logo
Hone
Problems

Task Scheduler in Rust

A task scheduler is a fundamental component in many operating systems and concurrent programming environments. This challenge asks you to implement a basic task scheduler in Rust that manages a set of tasks with associated priorities, ensuring higher-priority tasks are executed before lower-priority ones. This is useful for simulating real-world scenarios where certain operations need to be prioritized over others.

Problem Description

You are to implement a task scheduler that can add tasks with priorities, remove tasks, and execute tasks in order of priority. The scheduler should maintain a queue of tasks, sorted by priority (highest priority first). Tasks are represented by a simple Task struct containing a name (String) and a priority (u32).

What needs to be achieved:

  • Create a TaskScheduler struct that manages a collection of tasks.
  • Implement methods to add tasks to the scheduler with a given priority.
  • Implement a method to remove a task by name.
  • Implement a method to execute tasks in order of priority until the scheduler is empty. Execution should simply print the task name to the console.
  • Handle the case where a task to be removed doesn't exist.

Key Requirements:

  • Tasks should be stored in a data structure that allows for efficient sorting by priority.
  • The scheduler should handle duplicate task names gracefully (e.g., only remove the first occurrence).
  • The scheduler should not panic if a task is not found during removal.

Expected Behavior:

The scheduler should maintain tasks sorted by priority. When execute() is called, it should iterate through the tasks from highest priority to lowest, printing the name of each task.

Edge Cases to Consider:

  • Empty scheduler: execute() should do nothing.
  • Removing a non-existent task: Should not panic, and ideally provide some indication that the task wasn't found (e.g., print a message).
  • Tasks with the same priority: The order of tasks with the same priority is not specified and can be arbitrary.
  • Adding the same task multiple times: The scheduler should handle this without error, but the task will only be executed once per execution cycle.

Examples

Example 1:

Input:
scheduler = TaskScheduler::new();
scheduler.add_task("Task A".to_string(), 1);
scheduler.add_task("Task B".to_string(), 3);
scheduler.add_task("Task C".to_string(), 2);
scheduler.execute();

Output:

Task B
Task C
Task A

Explanation: Tasks are executed in descending order of priority (3, 2, 1).

Example 2:

Input:
scheduler = TaskScheduler::new();
scheduler.add_task("Task X".to_string(), 5);
scheduler.remove_task("Task Y".to_string()); // Task Y doesn't exist
scheduler.execute();

Output:

Task X

Explanation: Removing a non-existent task doesn't affect the scheduler's state, and the only task is executed.

Example 3: (Edge Case - Empty Scheduler)

Input:
scheduler = TaskScheduler::new();
scheduler.execute();

Output: (No output) Explanation: The scheduler is empty, so execute() does nothing.

Constraints

  • Task names are strings with a maximum length of 50 characters.
  • Task priorities are unsigned 32-bit integers (u32).
  • The scheduler should be able to handle at least 100 tasks without significant performance degradation.
  • The add_task and remove_task methods should complete within 10 milliseconds.
  • The execute method should complete within 50 milliseconds for a scheduler with 100 tasks.

Notes

Consider using a BinaryHeap from the standard library to efficiently manage tasks based on priority. Remember that BinaryHeap is a max-heap, so you might need to adapt your priority values accordingly. Think about how to handle the case where a task is not found during removal – returning a boolean indicating success/failure or printing an error message are both reasonable approaches. Focus on clarity and correctness first, then optimize for performance if necessary.

Loading editor...
rust