From 9099497185b5dd68933782a92336815d82454dbb Mon Sep 17 00:00:00 2001 From: Luke Granger-Brown Date: Sun, 14 Jun 2020 21:47:14 +0100 Subject: [PATCH] chore(clbot): Refactor backoff utility into a separate package. It'll be reused by the IRC side of things too. Change-Id: I3d84f3fd5fca6a6d948f331143b14f096d10675d Reviewed-on: https://cl.tvl.fyi/c/depot/+/342 Reviewed-by: tazjin --- fun/clbot/backoffutil/backoffutil.go | 43 ++++++++++++++++++++++++++++ fun/clbot/backoffutil/default.nix | 14 +++++++++ fun/clbot/gerrit/default.nix | 2 +- fun/clbot/gerrit/watcher.go | 29 ++----------------- 4 files changed, 60 insertions(+), 28 deletions(-) create mode 100644 fun/clbot/backoffutil/backoffutil.go create mode 100644 fun/clbot/backoffutil/default.nix diff --git a/fun/clbot/backoffutil/backoffutil.go b/fun/clbot/backoffutil/backoffutil.go new file mode 100644 index 000000000..1b1ea5f9d --- /dev/null +++ b/fun/clbot/backoffutil/backoffutil.go @@ -0,0 +1,43 @@ +// Package backoffutil provides useful utilities for backoff. +package backoffutil + +import ( + "time" + + backoff "github.com/cenkalti/backoff/v4" +) + +// ZeroStartingBackOff is a backoff.BackOff that returns "0" as the first Duration after a reset. +// This is useful for constructing loops and just enforcing a backoff duration on every loop, rather than incorporating this logic into the loop directly. +type ZeroStartingBackOff struct { + bo backoff.BackOff + initial bool +} + +// NewZeroStartingBackOff creates a new ZeroStartingBackOff. +func NewZeroStartingBackOff(bo backoff.BackOff) *ZeroStartingBackOff { + return &ZeroStartingBackOff{bo: bo, initial: true} +} + +// NewDefaultBackOff creates a sensibly configured BackOff that starts at zero. +func NewDefaultBackOff() backoff.BackOff { + ebo := backoff.NewExponentialBackOff() + ebo.MaxElapsedTime = 0 + return NewZeroStartingBackOff(ebo) +} + +// NextBackOff returns the next back off duration to use. +// For the first call after a call to Reset(), this is 0. For each subsequent duration, the underlying BackOff is consulted. +func (bo *ZeroStartingBackOff) NextBackOff() time.Duration { + if bo.initial == true { + bo.initial = false + return 0 + } + return bo.bo.NextBackOff() +} + +// Reset resets to the initial state, and also passes a Reset through to the underlying BackOff. +func (bo *ZeroStartingBackOff) Reset() { + bo.initial = true + bo.bo.Reset() +} diff --git a/fun/clbot/backoffutil/default.nix b/fun/clbot/backoffutil/default.nix new file mode 100644 index 000000000..78585da23 --- /dev/null +++ b/fun/clbot/backoffutil/default.nix @@ -0,0 +1,14 @@ +{ depot, ... }: + +let + inherit (depot.third_party) gopkgs; +in +depot.nix.buildGo.package { + name = "code.tvl.fyi/fun/clbot/backoffutil"; + srcs = [ + ./backoffutil.go + ]; + deps = [ + gopkgs."github.com".cenkalti.backoff.gopkg + ]; +} diff --git a/fun/clbot/gerrit/default.nix b/fun/clbot/gerrit/default.nix index 725b400e6..3b6ce0a73 100644 --- a/fun/clbot/gerrit/default.nix +++ b/fun/clbot/gerrit/default.nix @@ -11,7 +11,7 @@ depot.nix.buildGo.package { ]; deps = [ clbot.gerrit.gerritevents - gopkgs."github.com".cenkalti.backoff.gopkg + clbot.backoffutil gopkgs."github.com".golang.glog.gopkg gopkgs."golang.org".x.crypto.ssh.gopkg ]; diff --git a/fun/clbot/gerrit/watcher.go b/fun/clbot/gerrit/watcher.go index 80a431f92..d45876129 100644 --- a/fun/clbot/gerrit/watcher.go +++ b/fun/clbot/gerrit/watcher.go @@ -9,35 +9,12 @@ import ( "strings" "time" + "code.tvl.fyi/fun/clbot/backoffutil" "code.tvl.fyi/fun/clbot/gerrit/gerritevents" - "github.com/cenkalti/backoff/v4" log "github.com/golang/glog" "golang.org/x/crypto/ssh" ) -// zeroStartingBackOff is a backoff.BackOff that returns "0" as the first Duration after a reset. -// This is useful for constructing loops and just enforcing a backoff duration on every loop, rather than incorporating this logic into the loop directly. -type zeroStartingBackOff struct { - bo backoff.BackOff - initial bool -} - -// NextBackOff returns the next back off duration to use. -// For the first call after a call to Reset(), this is 0. For each subsequent duration, the underlying BackOff is consulted. -func (bo *zeroStartingBackOff) NextBackOff() time.Duration { - if bo.initial == true { - bo.initial = false - return 0 - } - return bo.bo.NextBackOff() -} - -// Reset resets to the initial state, and also passes a Reset through to the underlying BackOff. -func (bo *zeroStartingBackOff) Reset() { - bo.initial = true - bo.bo.Reset() -} - // closer provides an embeddable implementation of Close which awaits a main loop acknowledging it has stopped. type closer struct { stop chan struct{} @@ -174,9 +151,7 @@ func (c *restartingClient) runOnce() error { func (c *restartingClient) run() { defer close(c.stopped) - ebo := backoff.NewExponentialBackOff() - ebo.MaxElapsedTime = 0 - bo := &zeroStartingBackOff{bo: ebo, initial: true} + bo := backoffutil.NewDefaultBackOff() for { timer := time.NewTimer(bo.NextBackOff()) select {