今日已更新 80 条资讯 | 累计 20052 条内容
关于我们

Retries and Circuit Breakers Belong in the Adapter, Not Your Use Case

Gabriel Anhaia 2026年06月14日 05:44 2 次阅读 来源:Dev.to

Book: Decoupled PHP — Clean and Hexagonal Architecture for Applications That Outlive the Framework Also by me: Thinking in Go (2-book series) — Complete Guide to Go Programming + Hexagonal Architecture in Go My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools Me: xgabriel.com | GitHub You open a use case that places an order. It loads a customer, builds the order, charges a payment gateway, saves, publishes an event. Clean. Then a sprint ago someone added a retry loop around the charge call, because the gateway flaps under load. Now the use case has a for ($i = 0; $i < 3; $i++) , a usleep() , and a comment that says // gateway is flaky on Mondays . The business rule is buried under retry plumbing. A reader who wants to know what placing an order means has to skip past sleep timers and exception counters to find it. Worse, the next person who adds a second outbound call copies the loop. Soon every call to the network has its own hand-rolled retry, each with a slightly different backoff, none of them tested. The use case learned about transient failure. It should never have. Transient failure is not a business rule A use case answers one question: what does the application do when this thing happens? Place an order. Cancel a subscription. Issue a refund. Those are decisions the business cares about. "The payment gateway returned a 503 and we should try again in 200ms" is not a business decision. It is a property of the network between your process and theirs. The domain does not know the gateway is HTTP. It does not know there is a network at all. It asked a port to charge a customer, and the port either succeeds or raises a domain exception. Here is the port, stated in domain language: <?php declare ( strict_types = 1 ); namespace App\Application\Port ; use App\Domain\Customer\CustomerId ; use App\Domain\Shared\Money ; interface PaymentGateway { public function charge ( CustomerId $customerId , Money $amount , s

本文内容来源于互联网,版权归原作者所有
查看原文