Hone logo
Hone
Problems

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:

  1. When a task is added with a delay, it should be placed in the queue with a pending status.
  2. After the specified delay, the task's status should change to running.
  3. The asyncFunction should be executed.
  4. If the asyncFunction resolves successfully, the task's status should change to completed.
  5. If the asyncFunction rejects, the task's status should change to failed, and an error message should be displayed.
  6. The scheduler should only execute a maximum number of tasks concurrently as defined by the concurrencyLimit.
  7. 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 asyncFunction throws 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 delay value must be a non-negative integer.
  • The concurrencyLimit must be a positive integer.
  • The asyncFunction must return a Promise.
  • The component should be reasonably performant, even with a large number of tasks in the queue (consider using setTimeout appropriately).
  • 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 setTimeout to 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).
Loading editor...
typescript