Notification Service
Design ka core hai NotificationChannel interface (Email, SMS, Push, WhatsApp) plus ek Factory jo channel choose kare. User preferences respect karo — kisi ne SMS band kiya hai to mat bhejo. Templates ko data rakho, code mein string concatenation mat karo.
Reliability sabse important hai. Sending ASYNC honi chahiye (queue ke through), failure par RETRY with exponential backoff, aur baar-baar fail hone par DEAD LETTER QUEUE. Rate limiting bhi chahiye — provider ki apni limits hoti hain. Aur idempotency: ek hi notification do baar na jaaye.
interface NotificationChannel {
boolean send(Notification n);
ChannelType type();
}
class NotificationService {
void notify(User user, NotificationRequest req) {
for (ChannelType ch : user.getEnabledChannels(req.getCategory())) {
queue.publish(new NotificationJob(user, req, ch)); // async
}
}
}
class NotificationWorker {
void process(NotificationJob job) {
try { channelFactory.get(job.channel()).send(job.toNotification()); }
catch (TransientException e) {
if (job.attempts() < MAX_RETRY) queue.publishWithDelay(job.retry(), backoff(job));
else deadLetterQueue.publish(job);
}
}
}- NotificationChannel interface + Factory, user preferences respect karo
- Async queue + exponential backoff retry + dead letter queue
- Transient vs permanent failure ka farak — sab retry mat karo
Notification ka content code mein string concatenation se mat banao. Templates ko DATA rakho — placeholders ke saath ("Hi {name}, order {orderId} shipped"). Isse content team bina deploy ke text badal sakti hai.
Har channel ka apna template chahiye — SMS mein 160 character limit hai, email mein HTML chalta hai, push mein title+body. Ek hi template sab jagah use karna galat output deta hai.
record NotificationTemplate(String id, ChannelType channel, String subject, String body) {}
String render(NotificationTemplate t, Map<String, String> vars) {
String out = t.body();
for (var e : vars.entrySet()) out = out.replace("{" + e.getKey() + "}", e.getValue());
return out;
}Fixed interval retry (har 5 second) bura hai — provider down ho to sab clients ek saath hammer karte hain. EXPONENTIAL BACKOFF use karo: 1s, 2s, 4s, 8s.
Iske saath JITTER (thoda random) add karo, warna saare failed messages ek hi second par retry karenge — ye "thundering herd" problem hai. Max retry ke baad dead letter queue.
Duration backoff(int attempt) {
long base = (long) Math.pow(2, attempt) * 1000;
long jitter = ThreadLocalRandom.current().nextLong(0, base / 2);
return Duration.ofMillis(base + jitter); // jitter se thundering herd rukta hai
}