This project is a distributed job scheduling system built with Node.js, BullMQ, Redis, MongoDB, and Docker. It allows users to schedule jobs (such as sending emails) to be executed at a specific time. The system ensures that jobs execute only once even in a distributed environment, handling worker crashes and concurrency efficiently.
- Job Scheduling: Users can schedule tasks for future execution.
- Distributed Execution: Ensures a job runs only once, even across multiple workers.
- Fault Tolerance: If a worker crashes, another worker picks up the pending job.
- Concurrency Handling: Prevents duplicate execution of jobs.
- Efficiency: Handles a large number of scheduled jobs efficiently.
The system consists of:
- API Server (
server.js): Handles job creation requests. - Job Queue (
BullMQ&Redis): Manages job execution. - Worker Service (
worker.js): Processes jobs and prevents duplicate execution using Redlock (distributed locking). - Watcher Service (
watcher.js): Checks pending jobs and schedules them in the queue. - Database (
MongoDB): Stores job details. - Docker: Runs MongoDB and Redis as containers for easier deployment.
git clone https://github.com/your-repo/job-scheduler.git
cd job-schedulernpm installOpen docker Desktop and Run the following command to start Redis
docker run --name my-redis -p 6379:6379 -d redisFor mongodb
docker run -d --name mongodb -p 27017:27017 -v mongodata:/data/db mongo:latestThis will start MongoDB and Redis in the background.
Go to your google account . Then go security search for app password .Create App password to use in nodemailer . And user is your email_id
user : email_id
pass : your_APP_PASSMONGO_URI=mongodb://127.0.0.1:27017/job-scheduler
Run the server:
npm run devRun the job watcher:
cd service
node watcher.jsRun the worker service:
cd service
node worker.jsTo Scale multiple worker use
node worker.js
node worker.js
node worker.jsEndpoint: POST /api/v1/create-job
Request Body:
{
"type": "email",
"data": {
"to": "user@example.com",
"subject": "Scheduled Email",
"message": "This is a test email."
},
"scheduledTime": "2025-02-12T12:47:00"
}Response:
{
"success": true,
"job": {
"type": "email",
"data": {
"to": "email_id",
"subject": "subject ",
"message": "test message"
},
"status": "pending",
"scheduledTime": "2025-02-12T07:17:00.000Z",
"_id": "67ac4aa3cf3d9d990bd9f22fm",
"createdAt": "2025-02-12T07:15:47.787Z",
"__v": 0
}
}Endpoint: GET /api/v1/jobs
Endpoint: GET /api/v1/job/:id
- A user schedules a job via API (
/api/v1/create-job). - The job is stored in MongoDB with a
pendingstatus. - The watcher (
watcher.js) runs every minute and checks for jobs that need to be executed. - Pending jobs are added to the Redis job queue (
BullMQ). - The worker (
worker.js) processes the job, sending an email if required. - The worker updates the job status to
completedin MongoDB. - If a worker crashes, another worker picks up the pending jobs using Redis-based locking.