Skip to content

AkP2809/TaskHive

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TaskHive — Distributed Job Processing System

A distributed job processing system built with Java 21, Spring Boot, RabbitMQ, and PostgreSQL.

Architecture

Client (REST)
   │
   ▼
API Service (Spring Boot :8080)
   │
   ▼
RabbitMQ (job.exchange → job.queue ↔ job.dlq)
   │
   ▼
Worker Service (Spring Boot :8081)
   │
   ▼
PostgreSQL

Tech Stack

  • Java 21 (Zulu OpenJDK)
  • Spring Boot 3.4.3 (Web, Data JPA, AMQP, Actuator, Retry)
  • RabbitMQ 3.13 (with management UI)
  • PostgreSQL 16
  • Docker Compose
  • Flyway (database migrations)
  • Micrometer + Prometheus (observability)

Quick Start

Prerequisites

  • Java 21
  • Maven 3.9+
  • Docker & Docker Compose

Run with Docker Compose

docker-compose up --build

Run Locally (Development)

  1. Start infrastructure:
docker-compose up postgres rabbitmq
  1. Build:
mvn clean install -DskipTests
  1. Run API Service:
mvn spring-boot:run -pl api-service
  1. Run Worker Service (in another terminal):
mvn spring-boot:run -pl worker-service

API Endpoints

Method Endpoint Description
POST /api/v1/jobs Submit a new job
GET /api/v1/jobs/{id} Get job details
GET /api/v1/jobs List jobs (paginated)
DELETE /api/v1/jobs/{id} Cancel a pending job
GET /api/v1/jobs/{id}/attempts Get retry history

Submit a Job

curl -X POST http://localhost:8080/api/v1/jobs \
  -H "Content-Type: application/json" \
  -d '{
    "type": "EMAIL",
    "priority": "HIGH",
    "payload": {
      "to": "user@example.com",
      "subject": "Welcome!",
      "body": "Hello from TaskHive"
    }
  }'

Job Types

  • EMAIL — Sends an email notification
  • REPORT — Generates a report (PDF/CSV)
  • DATA_EXPORT — Runs an ETL data export pipeline

Monitoring & Observability

Start the full stack including monitoring:

docker-compose up --build

Access Points

Service URL Credentials
Grafana http://localhost:3000 admin / taskhive
Prometheus http://localhost:9090
RabbitMQ Management http://localhost:15672 taskhive / taskhive_secret
API Actuator http://localhost:8080/actuator/health
Prometheus Metrics http://localhost:8080/actuator/prometheus

Pre-Provisioned Dashboard: Job Processing Overview

The Grafana dashboard loads automatically with 10 panels:

Panel Type What It Shows
Jobs Submitted Time series Submission rate per minute
Jobs Completed Time series Completion rate per minute
Jobs Failed Time series Failure rate per minute
Total Jobs Stat Cumulative submitted / completed / failed counters
Job Success Rate Gauge Percentage (red < 80%, orange < 95%, green ≥ 95%)
Processing Duration Time series p50 and p95 execution time
HTTP Request Rate Time series API endpoint request rates by method/uri/status
HTTP Response Time Time series API endpoint latency p95
JVM Heap Memory Time series Heap usage per service
DB Connection Pool Time series HikariCP active/idle connections

Testing

Run all tests:

mvn test

Test Summary (29 tests)

Test Class Tests Coverage
JobServiceTest 9 Submit (afterCommit), get, cancel (state validation), attempts
JobControllerTest 5 HTTP 201/200/404/409, JSON response validation
JobExecutorTest 5 Strategy resolution, success/failure, DLQ on max retries, metrics
JobListenerTest 4 Execute, skip cancelled, skip not-found, throw for DLQ retry
DeadLetterListenerTest 3 Retry with increment, drop on exhaust, boundary condition
EmailJobHandlerTest 3 Correct type, execution result, missing fields graceful handling

Notable Fix: Race Condition & afterCommit Pattern

RabbitMQ messages are published after the database transaction commits using TransactionSynchronizationManager.afterCommit(). This prevents a race condition where the worker receives a job message before the job row is visible in PostgreSQL — a common gotcha in async systems with transactional writes + message queues.

Notable Fix: Spring Boot 3.4.x Test Compatibility

Spring Boot 3.4.x deprecated @MockBean in favor of @MockitoBean (org.springframework.test.context.bean.override.mockito). Controller tests use standalone MockMvcBuilders.standaloneSetup() instead of @WebMvcTest to avoid auto-configuring JPA/RabbitMQ during test context loading.

Project Structure

TaskHive/
├── common/              (shared entities, DTOs, config)
├── api-service/         (REST API + job producer)
├── worker-service/      (job consumer + execution engine)
├── monitoring/
│   ├── prometheus/      (scrape config)
│   └── grafana/         (provisioning + dashboard JSONs)
├── docker-compose.yml
└── pom.xml              (parent POM)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors