Asynchronous Task Scheduler in Vue.js
This challenge asks you to build a simple asynchronous task scheduler within a Vue.js component. Such a scheduler is useful for managing and executing tasks (like API calls, data processing, or UI updates) with controlled timing and concurrency, preventing overwhelming the application and improving responsiveness. You'll be creating a component that allows users to add tasks to a queue, schedule them for execution at specific times, and limit the number of tasks running concurrently.
Problem Description
You need to create a Vue.js component called AsyncScheduler that manages a queue of asynchronous tasks. Each task is an object with a name (string) and an asyncFunction (a function that returns a Promise). The scheduler should allow adding tasks to the queue, scheduling them for execution at a specified delay (in milliseconds), and limiting the number of tasks running concurrently.
Key Requirements:
- Task Queue: Maintain a queue of tasks to be executed.
- Scheduling: Allow adding tasks with a delay before execution.
- Concurrency Control: Limit the number of tasks running simultaneously.
- Error Handling: Handle potential errors within the asynchronous tasks gracefully.
- Status Tracking: Provide a way to track the status of each task (pending, running, completed, failed).
- Clear UI: Display the task queue, their status, and any error messages.
Expected Behavior:
- When a task is added with a delay, it should be placed in the queue with a
pendingstatus. - After the specified delay, the task's status should change to
running. - The
asyncFunctionshould be executed. - If the
asyncFunctionresolves successfully, the task's status should change tocompleted. - If the
asyncFunctionrejects, the task's status should change tofailed, and an error message should be displayed. - The scheduler should only execute a maximum number of tasks concurrently as defined by the
concurrencyLimit. - When a task completes (either successfully or with an error), the next task in the queue should be started (if available and concurrency limit allows).
Edge Cases to Consider:
- Tasks added with a delay of 0 should be executed immediately (if concurrency allows).
- What happens if a task fails? Should it be retried? (For this challenge, assume no retry mechanism).
- What happens if the queue is empty?
- What happens if the
asyncFunctionthrows an error synchronously (before resolving or rejecting)? - How to handle tasks with very long delays?
Examples
Example 1:
Input:
tasks = [
{ name: "Task 1", asyncFunction: () => new Promise(resolve => setTimeout(() => resolve("Task 1 completed"), 1000)) },
{ name: "Task 2", asyncFunction: () => new Promise(resolve => setTimeout(() => resolve("Task 2 completed"), 500)) },
{ name: "Task 3", asyncFunction: () => new Promise(resolve => setTimeout(() => resolve("Task 3 completed"), 1500)) }
]
delay = 0
concurrencyLimit = 1
Output:
Task 1: completed (after 1 second)
Task 2: completed (after 0.5 seconds)
Task 3: completed (after 1.5 seconds)
Explanation: Since concurrency is 1, tasks are executed sequentially. Task 2 starts immediately because delay is 0.
Example 2:
Input:
tasks = [
{ name: "Task 1", asyncFunction: () => new Promise(resolve => setTimeout(() => resolve("Task 1 completed"), 1000)) },
{ name: "Task 2", asyncFunction: () => new Promise(resolve => setTimeout(() => resolve("Task 2 completed"), 500)) },
{ name: "Task 3", asyncFunction: () => new Promise((resolve, reject) => setTimeout(() => reject("Task 3 failed"), 1500)) }
]
delay = 0
concurrencyLimit = 2
Output:
Task 1: completed (after 1 second)
Task 2: completed (after 0.5 seconds)
Task 3: failed (after 1.5 seconds)
Explanation: With concurrency 2, Task 1 and Task 2 start immediately. Task 3 fails after 1.5 seconds.
Example 3: (Edge Case)
Input:
tasks = [
{ name: "Task 1", asyncFunction: () => new Promise(resolve => setTimeout(() => resolve("Task 1 completed"), 1000)) },
]
delay = 2000
concurrencyLimit = 1
Output:
Task 1: completed (after 2 seconds)
Explanation: Task 1 is scheduled with a 2-second delay and executed after that delay.
Constraints
- The
delayvalue must be a non-negative integer. - The
concurrencyLimitmust be a positive integer. - The
asyncFunctionmust return a Promise. - The component should be reasonably performant, even with a large number of tasks in the queue (consider using
setTimeoutappropriately). - The Vue component should be reactive, updating the UI as tasks are added, scheduled, and completed/failed.
Notes
- You can use Vue's reactivity system (e.g.,
ref,reactive) to manage the task queue and their statuses. - Consider using
setTimeoutto implement the scheduling delay. - Think about how to handle errors gracefully and provide informative error messages to the user.
- Focus on the core scheduling logic and concurrency control. You don't need to implement a complex UI, but the UI should clearly display the task queue and their statuses.
- This is a simplified scheduler. Real-world schedulers often have more features (e.g., task prioritization, cancellation, retries).