Repository navigation
Phase 11.7 — Email Retry System (Production-Ready) #49
Description
Activity
Assign me.
Reacted by Vimal Patel- addedenhancementNew feature or requestNew feature or requesthelp wantedExtra attention is neededExtra attention is neededquestionFurther information is requestedFurther information is requested
on Apr 13, 2026 If any Error at the VPS level, do below 1st,
docker stop vimaltech-contact-api-blue docker rm vimaltech-contact-api-blue docker image rm ghcr.io/vimal-java-dev/vimaltech-contact-api:latest docker pull ghcr.io/vimal-java-dev/vimaltech-contact-api:latest ./deploy.sh
👉 Ensure it shows MAIL_HOST (NOT SPRING_MAIL_HOST)
docker exec -it vimaltech-contact-api-green printenv | grep MAIL
MAIL_HOST=smtp.zoho.in MAIL_PORT=587 MAIL_USERNAME=vimal.patel@vimaltech.dev MAIL_PASSWORD=xxxxxxxxxxxxxxx APP_MAIL_FROM=vimal.patel@vimaltech.dev APP_ADMIN_EMAIL=vimal.patel@vimaltech.dev
DEBUG at VPS Level
Run:
docker logs vimaltech-contact-api-green -f
docker logs vimaltech-contact-api-green | grep EmailService
Then hit the API.
🧠 Final Architecture (Clean & Production-Ready)
Flow becomes:
API Request
↓
Async EmailService
↓
DB (PENDING)
↓
SMTP Send
↓
SENT or FAILED
↓
Scheduler
↓
Retry FAILED
↓
Final SENT or STOP after max retries
✅ What We Already Did Correctly
Our current system already has:
✅ Interface-based email abstraction
✅ Async execution isolated in the SMTP layer
✅ Dedicated thread pool
✅ DTO separation (EmailRequest)
✅ Contact persistence independent from email sending
✅ Proper logging
✅ Reply-To support
✅ Profile-based SMTP activationThis means:
👉 We should extend, not redesign.
✅ Correct Design For YOUR Existing System
We should NOT:
- Modify ContactService heavily
- Create Kafka-like complexity
- Add Redis
- Introduce queues
Instead:
🔷 We Will Add
Component Purpose EmailLog entity persistent email tracking EmailStatus enum SENT / FAILED / PENDING EmailLogRepository retry querying EmailRetryScheduler periodic retry small refactor in SmtpEmailService central retry handling From your project root:
docker compose downThen rebuild + start:
docker compose up --build
✅ Recommended (Detached Mode)
Usually better:
docker compose up --build -d✅ Then Check Logs
Watch startup logs:
docker compose logs -f contact-apiOR if your service name is different:
docker compose psto see the actual service name.
✅ What You Should See
Hibernate should create:
email_logsLook for logs similar to:
create table email_logsor
alter table email_logs
✅ Then Verify Inside PostgreSQL Container
Enter DB container:
docker exec -it vimaltech-postgres psql -U contactuser -d contactdb
If your container name differs:
docker ps✅ Create a DEV Email Implementation
✅ Current StatusComponent Status EmailStatus enum ✅ EmailLog entity ✅ EmailLogRepository ✅ PostgreSQL schema ✅ Docker integration ✅ Dev profile separation ✅ Email bean architecture ✅
⚠️ IMPORTANT ARCHITECTURAL CHANGERight now, your SMTP service:
- only sends mail
- does NOT persist state
We will now make it:
- persistence-aware
- retry-aware
- production-safe
WITHOUT breaking existing callers.
🔷 STEP 1 — Update EmailService Interface
🔷 STEP 2 — Update DevEmailService
🔥 NOW: Refactor SmtpEmailService
This is the core of Phase 11.7.
We will do this carefully in small, controlled steps.
================
⚠️ IMPORTANT GOALCurrent behavior:
send email
↓
if fails
↓
log onlyNew behavior:
create EmailLog row
↓
attempt SMTP send
↓
update SENT / FAILED
↓
scheduler retries FAILED later
We’ve now completed:
Phase 11.7 core implementation
- Flyway integration
- retry scheduler
- production-safe schema management
- logging cleanup
- retry validation end-to-end
And our latest logs confirm Step 3 succeeded correctly, including safe idempotent migrations with:
already exists, skipping.which is expected because of IF NOT EXISTS.
Reacted by Vimal PatelPhase 11.7 — Step 4
Optimize Retry Scheduler Efficiency
Production Benefits
This is a real enterprise-grade improvement.
We gain:✅ lower DB scans
✅ faster scheduler execution
✅ reduced CPU usage
✅ cleaner retry queue
✅ operational clarity
✅ easier monitoring/analytics
✅ future dashboard support
Expected Final Flow
Create Email
↓
PENDING
↓
Send Success → SENTOR
Send Failure
↓
FAILED
↓
Scheduler Retry
↓
Success → SENTOR
Retries Exhausted
↓
FAILED_PERMANENT
This Is a Strong Production Feature
Most beginner retry systems stop at:
FAILED foreverMy implementation now demonstrates:
- retry lifecycle management
- queue hygiene
- operational optimization
- scheduler efficiency
- production-aware state transitions
This is genuinely strong backend engineering for a portfolio project.
After Completing Step 4
Our retry system will now include:
✅ async email sending
✅ retry mechanism
✅ exponential/backoff-ready architecture
✅ retry counting
✅ scheduler retry processing
✅ terminal failure state
✅ retry queue optimization
✅ production-grade lifecycle managementThat becomes a very credible enterprise backend feature set.
Reacted by Vimal PatelCheck My PR. #51
Reacted by Vimal Patel
Context:
Requirements:
Proceed step-by-step.