From 8cd5c6bf0545a51cf1d79a1e3a3277b085c38065 Mon Sep 17 00:00:00 2001 From: jjpinto Date: Sat, 24 Jan 2026 11:09:13 -0500 Subject: [PATCH] Fix HTTP response body leak and add retry backoff in run.go sendCountRequest() never closed resp.Body, causing file descriptor and connection leaks under load. This eventually leads to "too many open files" and stalled requests. The retry loop also hammered the server with no delay on non-204 responses. A small backoff prevents excessive CPU and network usage. This makes the exactly-once example more reliable and prevents false failures. Fix https://github.com/ThreeDotsLabs/watermill/issues/664 --- .../exactly-once-delivery-counter/run.go | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/_examples/real-world-examples/exactly-once-delivery-counter/run.go b/_examples/real-world-examples/exactly-once-delivery-counter/run.go index cb4ead13d..dc4aa1174 100644 --- a/_examples/real-world-examples/exactly-once-delivery-counter/run.go +++ b/_examples/real-world-examples/exactly-once-delivery-counter/run.go @@ -136,16 +136,20 @@ func restartMySQL() { } func sendCountRequest(counterUUID string) { - for { - resp, err := http.Post("http://localhost:8080/count/"+counterUUID, "", nil) - if err != nil { - continue - } - - if resp.StatusCode == http.StatusNoContent { - break - } - } + for { + resp, err := http.Post("http://localhost:8080/count/"+counterUUID, "", nil) + if err != nil { + time.Sleep(100 * time.Millisecond) + continue + } + resp.Body.Close() + + if resp.StatusCode == http.StatusNoContent { + break + } + + time.Sleep(100 * time.Millisecond) + } } func createDB() *stdSQL.DB {