From e5302041072327312829d06a98508be2e2795446 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 24 Apr 2018 21:26:06 +0300 Subject: [PATCH] use randomized exponential backoff in error retry for persistent client registrations --- client.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/client.go b/client.go index 6e4e0d4..e65b690 100644 --- a/client.go +++ b/client.go @@ -3,6 +3,7 @@ package rendezvous import ( "context" "fmt" + "math/rand" "time" pb "github.com/libp2p/go-libp2p-rendezvous/pb" @@ -92,9 +93,21 @@ func Register(ctx context.Context, rz Rendezvous, ns string, ttl int) error { } func registerRefresh(ctx context.Context, rz Rendezvous, ns string, ttl int) { - refresh := time.Duration(ttl-30) * time.Second + var refresh time.Duration + errcount := 0 for { + if errcount > 0 { + // do randomized exponential backoff, up to ~4 hours + if errcount > 7 { + errcount = 7 + } + backoff := 2 << uint(errcount) + refresh = 5*time.Minute + time.Duration(rand.Intn(backoff*60000))*time.Millisecond + } else { + refresh = time.Duration(ttl-30) * time.Second + } + select { case <-time.After(refresh): case <-ctx.Done(): @@ -104,6 +117,9 @@ func registerRefresh(ctx context.Context, rz Rendezvous, ns string, ttl int) { err := rz.Register(ctx, ns, ttl) if err != nil { log.Errorf("Error registering [%s]: %s", ns, err.Error()) + errcount++ + } else { + errcount = 0 } } }