Careeroza
Real World Example
Order Confirmation Fan-Out
When you order on Swiggy or Flipkart, the "Order placed" screen appears instantly, while email, SMS, push notification and invoice PDF arrive a few seconds later. ShopEase does the same: the controller responds after saving the order, and the slow work runs in parallel on a dedicated pool.
@Service
@Slf4j
@RequiredArgsConstructor
public class OrderConfirmationService {
private final NotificationService notifications; // methods are @Async("notificationExecutor")
private final InvoiceService invoices; // @Async too
public void confirm(Order order) {
CompletableFuture<Boolean> email = notifications.sendEmail(order.getUser().getEmail(), order.getId());
CompletableFuture<Boolean> sms = notifications.sendSms(order.getUser().getPhone(), "Order " + order.getId() + " confirmed");
CompletableFuture<String> pdf = invoices.generateInvoice(order.getId());
CompletableFuture.allOf(email, sms, pdf)
.orTimeout(10, TimeUnit.SECONDS)
.whenComplete((v, ex) -> {
if (ex != null) log.warn("Some notifications failed for {}: {}", order.getId(), ex.getMessage());
});
}
}Example
curl -X POST localhost:8080/api/orders -H "Content-Type: application/json" -d '{"userId":7,"items":[{"productId":3,"quantity":1}]}'Example output
HTTP/1.1 201 Created
{"orderId":1001,"status":"PLACED","total":54999.00}
INFO [notify-1] NotificationService : email sent to [email protected]
INFO [notify-2] NotificationService : sms sent to +91-98XXXXXX21
INFO [notify-3] InvoiceService : invoice INV-1001.pdf generatedTip: If a notification must never be lost, write it to a database table or a message queue (Kafka/RabbitMQ) instead of a memory thread pool. See the Microservices material.