Skip to content

jwirick06/Taskd

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Taskd - Distributed Task Scheduler

Java Maven JUnit

A high-performance, thread-safe distributed task scheduling system with priority queues, retry mechanisms, and comprehensive metrics. Built with enterprise-level design patterns and best practices.

Features

Core Capabilities

  • Priority-Based Scheduling - Tasks executed based on configurable priority levels (CRITICAL, HIGH, MEDIUM, LOW)
  • Concurrent Execution - Multi-threaded task processing with configurable worker pool size
  • Automatic Retry - Configurable retry logic with exponential backoff for failed tasks
  • Task Cancellation - Cancel scheduled tasks before execution
  • Cron-like Scheduling - Support for recurring tasks using cron expressions
  • Real-time Metrics - Comprehensive performance and execution metrics
  • Thread-Safe Design - Fully concurrent-safe using Java's concurrent utilities

Design Patterns Implemented

  • Strategy Pattern - Pluggable task execution strategies
  • Decorator Pattern - Metrics collection through wrapping
  • Builder Pattern - Fluent task construction
  • Observer Pattern - Task lifecycle hooks
  • Factory Pattern - Thread creation and management

Architecture

┌─────────────────────────────────────────────────────┐
│              MetricsTaskScheduler                   │
│                  (Decorator)                        │
└─────────────────────┬───────────────────────────────┘
                      │
┌─────────────────────▼───────────────────────────────┐
│         DistributedTaskScheduler                    │
│     ┌─────────────┐  ┌──────────────┐               │
│     │ TaskQueue   │  │ TaskExecutor │               │
│     │ (Priority)  │  │  (Strategy)  │               │
│     └─────────────┘  └──────────────┘               │
│            ↓                  ↓                     │
│  ┌─────────────────────────────────────┐            │
│  │    Executor Service (Thread Pool)   │            │
│  └─────────────────────────────────────┘            │
└─────────────────────────────────────────────────────┘

Quick Start

Prerequisites

  • Java 23 or higher
  • Maven 3.8+

Installation

  1. Clone the repository:
git clone https://github.com/jwirick06/Taskd.git
cd Taskd
  1. Build the project:
mvn clean install
  1. Run tests:
mvn test
  1. Run the demo:
mvn exec:java -Dexec.mainClass="com.taskscheduler.TaskSchedulerDemo"

Usage Examples

Basic Task Scheduling

// Create scheduler components
PriorityTaskQueue queue = new PriorityTaskQueue();
SimpleTaskExecutor executor = new SimpleTaskExecutor();
DistributedTaskScheduler scheduler = new DistributedTaskScheduler(queue, executor);

// Start the scheduler
scheduler.start();

// Create and schedule a task
Task task = Task.builder()
    .name("Data Processing Task")
    .description("Process user data")
    .priority(Priority.HIGH)
    .action(() -> {
        // Your task logic here
        System.out.println("Processing data...");
    })
    .build();

CompletableFuture<TaskResult> future = scheduler.scheduleTask(task);

// Wait for result
TaskResult result = future.get();
System.out.println("Task completed: " + result.isSuccess());

// Shutdown gracefully
scheduler.shutdown();

With Metrics Tracking

// Wrap scheduler with metrics
MetricsTaskScheduler scheduler = new MetricsTaskScheduler(baseScheduler);
scheduler.start();

// Schedule multiple tasks
for (int i = 0; i < 100; i++) {
    Task task = createTask("Task " + i);
    scheduler.scheduleTask(task);
}

// Get metrics
TaskMetrics metrics = scheduler.getMetrics();
System.out.println("Success Rate: " + metrics.getSuccessRate() + "%");
System.out.println("Average Execution Time: " + metrics.getAverageExecutionTimeMs() + "ms");

Task with Retry Logic

Task resilientTask = Task.builder()
    .name("Flaky Network Call")
    .priority(Priority.CRITICAL)
    .maxRetries(3)
    .action(() -> {
        // Code that might fail
        if (networkUnavailable()) {
            throw new RuntimeException("Network error");
        }
        processData();
    })
    .build();

scheduler.scheduleTask(resilientTask);

Cron-based Recurring Tasks

// Create a task that runs every Monday at 9:00 AM
Task recurringTask = Task.builder()
    .name("Weekly Report")
    .priority(Priority.MEDIUM)
    .cronExpression("0 9 * * MON")
    .action(() -> generateWeeklyReport())
    .build();

scheduler.scheduleTask(recurringTask);

Task Cancellation

Task longTask = Task.builder()
    .name("Long Running Analysis")
    .priority(Priority.LOW)
    .action(() -> performAnalysis())
    .build();

CompletableFuture<TaskResult> future = scheduler.scheduleTask(longTask);

// Cancel if needed
boolean cancelled = scheduler.cancelTask(longTask.getId());
if (cancelled) {
    System.out.println("Task cancelled successfully");
}

Core Components

Task

Immutable task representation with metadata, priority, and execution context. Built using the Builder pattern for flexibility.

Key Properties:

  • id - Unique identifier
  • name - Human-readable name
  • priority - Execution priority (CRITICAL, HIGH, MEDIUM, LOW)
  • action - Runnable containing task logic
  • status - Current lifecycle state
  • retryCount / maxRetries - Retry configuration
  • cronExpression - Optional cron schedule

TaskScheduler

Core interface for scheduling operations. Implementations handle task queuing, execution, and lifecycle management.

Main Operations:

  • scheduleTask(Task) - Submit task for execution
  • cancelTask(String) - Cancel a scheduled task
  • start() / shutdown() - Lifecycle management

PriorityTaskQueue

Thread-safe priority queue using PriorityBlockingQueue. Tasks ordered by:

  1. Priority level (CRITICAL > HIGH > MEDIUM > LOW)
  2. Scheduled time (earlier first for same priority)

TaskExecutor

Strategy interface for task execution with lifecycle hooks:

  • beforeExecution(Task) - Pre-execution hook
  • execute(Task) - Main execution
  • afterExecution(Task) - Success hook
  • onExecutionFailure(Task, Throwable) - Failure handler

TaskMetrics

Thread-safe metrics collection using atomic operations:

  • Tasks scheduled/completed/failed/cancelled
  • Execution time statistics
  • Success rate calculation
  • Average execution time

Testing

The project includes a comprehensive test suite with 90%+ code coverage:

  • Unit Tests - Individual component testing
  • Integration Tests - End-to-end scheduler testing
  • Concurrency Tests - Thread-safety validation
  • Performance Tests - Load and stress testing

Run all tests:

mvn test

Run with coverage:

mvn test jacoco:report

Performance Characteristics

  • Throughput: 1000+ tasks/second (4 worker threads, simple tasks)
  • Latency: Sub-millisecond scheduling overhead
  • Memory: O(n) where n is number of queued tasks
  • Thread-Safety: Lock-free where possible, fine-grained locking elsewhere

Configuration

Worker Threads

// Default: Runtime.getRuntime().availableProcessors()
DistributedTaskScheduler scheduler = new DistributedTaskScheduler(queue, executor, 8);

Task Retry

Task task = Task.builder()
    .maxRetries(5)  // Default: 3
    .build();

Queue Capacity

PriorityTaskQueue queue = new PriorityTaskQueue(1000); // Initial capacity

Advanced Features

Custom Task Executor

public class LoggingTaskExecutor implements TaskExecutor {
    @Override
    public void execute(Task task) throws Exception {
        logger.info("Executing: " + task.getName());
        task.getAction().run();
    }
    
    @Override
    public void onExecutionFailure(Task task, Throwable throwable) {
        logger.error("Failed: " + task.getName(), throwable);
        alerting.sendAlert(task, throwable);
    }
}

Task Result Handling

CompletableFuture<TaskResult> future = scheduler.scheduleTask(task);

future.thenAccept(result -> {
    if (result.isSuccess()) {
        System.out.println("Completed in " + result.getDuration().toMillis() + "ms");
    } else {
        result.getError().ifPresent(error -> 
            System.err.println("Failed: " + error.getMessage())
        );
    }
});

Dependencies

  • SLF4J (2.0.12) - Logging facade
  • Jackson (2.17.0) - JSON processing
  • JUnit Jupiter (5.10.2) - Testing framework
  • Mockito (5.11.0) - Mocking framework
  • Awaitility (4.2.1) - Async testing utilities

Best Practices Demonstrated

  1. SOLID Principles - Single responsibility, interface segregation, dependency inversion
  2. Immutability - Task objects are immutable for thread-safety
  3. Defensive Copying - Protecting internal state
  4. Fail-Fast - Early validation and clear error messages
  5. Clean Code - Readable, well-documented, maintainable
  6. Comprehensive Testing - Unit, integration, and concurrency tests
  7. Proper Resource Management - Graceful shutdown and cleanup
  8. Thread-Safety - Proper use of concurrent collections and synchronization

Future Enhancements

  • Persistent task storage (database/Redis)
  • REST API for remote task submission
  • Web dashboard for monitoring
  • Task dependency graphs (DAG execution)
  • Dead letter queue for failed tasks
  • Rate limiting per task type
  • Task timeout configuration

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages