From e4e642a95741c494990b0c8126988d1fd3a5449c Mon Sep 17 00:00:00 2001 From: Marcelo Magallon Date: Wed, 7 Apr 2021 15:46:46 -0600 Subject: [PATCH] Use exponential backoff for read deadline (#162) Before this change, pinging any target once takes ~ 100 ms (the time it takes for Run() to return, not the RTT). After this change, it takes a time comparable to the RTT. The change comes from ReadFrom blocking for the specified delay if the done signal hasn't fired yet. It also improves a little the time it takes to ping a single target multiple times. Since this is exponential backoff in the way Ethernet does it (random delay, with an increasing maximum value, only changing in case of a timeout), the delay neither necessarily doubles nor increases each time the operation has to be retried, but it does eventually settle on the higher end of the possibilities if there are many timeouts. Signed-off-by: Marcelo E. Magallon Committed-by: Marcelo E. Magallon Committed-by: Charlie Jonas --- ping.go | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/ping.go b/ping.go index d9ba68f..520efb8 100644 --- a/ping.go +++ b/ping.go @@ -512,19 +512,42 @@ func (p *Pinger) Statistics() *Statistics { return &s } +type expBackoff struct { + baseDelay time.Duration + maxExp int64 + c int64 +} + +func (b *expBackoff) Get() time.Duration { + if b.c < b.maxExp { + b.c++ + } + + return b.baseDelay * time.Duration(rand.Int63n(1<