A structured mentorship engagement focused on backend engineering fundamentals. The work covered message queue architecture, extensible system design, batch processing patterns, and test-driven development. Every project was built from scratch with production quality as the target, not just passing requirements.
Messaging System
The system needed to support two delivery modes from a single interface: immediate dispatch and scheduled delivery. A naive implementation would have split the producer logic into two separate paths, duplicating message construction and routing responsibility.
I built it on RabbitMQ with a routing layer that selects the delivery path based on message configuration. Immediate messages are pushed to a direct exchange. Scheduled messages are held and dispatched by a cron worker at the configured time. Both paths share the same message format and producer interface — callers choose a delivery mode, not a delivery mechanism.
Extensible Provider Design
Integrating multiple external providers for the same operation — where the interface is identical but the underlying implementation differs — is a common pattern that becomes a maintenance problem when provider selection is handled with branches inside the sending logic.
I used the abstract factory pattern: a factory per provider, a common interface, and a registry that selects the right factory based on configuration. The send path never changes when a new provider is added. Adding support for a new provider means adding a new factory class. The existing code is not modified. This is the open-closed principle applied directly: open for extension, closed for modification.
Batch Processing and Resilience
Batch jobs that call external services need to handle partial failures without stopping the run, and they need to protect against hammering a degraded downstream with unbounded retries.
I implemented retry with exponential backoff at the per-item level so a single failing record does not block the rest of the batch. A circuit breaker sits at the service boundary: if the downstream failure rate crosses a threshold, the circuit opens and the batch fails fast rather than continuing to exhaust retries against a service that is already struggling. The batch can resume safely from where it left off once the downstream recovers.