diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 0f72666..32fe1f4 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -11,7 +11,7 @@ on: # yamllint disable-line rule:truthy types: - "checks_requested" env: - GO_VERSION: "~1.24.0" + GO_VERSION: "~1.24.13" jobs: go-lint: name: "Lint Go" diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index a9fb062..8aa15b4 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -11,7 +11,7 @@ on: # yamllint disable-line rule:truthy types: - "checks_requested" env: - GO_VERSION: "~1.24.0" + GO_VERSION: "~1.24.13" jobs: unit: name: "Unit" diff --git a/go.mod b/go.mod index ab230fe..4c5d7ff 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,6 @@ require ( github.com/google/uuid v1.6.0 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 github.com/jackc/pgx/v5 v5.7.5 - github.com/lthibault/jitterbug v2.0.0+incompatible github.com/magefile/mage v1.15.0 github.com/prometheus/client_golang v1.22.0 github.com/rs/zerolog v1.34.0 diff --git a/go.sum b/go.sum index e1bb8a6..18e0f63 100644 --- a/go.sum +++ b/go.sum @@ -33,8 +33,6 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lthibault/jitterbug v2.0.0+incompatible h1:qouq51IKzlMx25+15jbxhC/d79YyTj0q6XFoptNqaUw= -github.com/lthibault/jitterbug v2.0.0+incompatible/go.mod h1:2l7akWd27PScEs6YkjyUVj/8hKgNhbbQ3KiJgJtlf6o= github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg= github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= diff --git a/pkg/health.go b/pkg/health.go index f704220..bc10a94 100644 --- a/pkg/health.go +++ b/pkg/health.go @@ -7,7 +7,6 @@ import ( "time" "github.com/jackc/pgx/v5" - "github.com/lthibault/jitterbug" "github.com/prometheus/client_golang/prometheus" "golang.org/x/time/rate" @@ -57,19 +56,30 @@ func NewNodeHealthChecker(url string) (*NodeHealthTracker, error) { // Poll starts polling the cluster and recording the node IDs that it sees. func (t *NodeHealthTracker) Poll(ctx context.Context, interval time.Duration) { - ticker := jitterbug.New(interval, jitterbug.Uniform{ - // nolint:gosec - // G404 use of non cryptographically secure random number generator is not concern here, - // as it's used for jittering the interval for health checks. - Source: rand.New(rand.NewSource(time.Now().Unix())), - Min: interval, - }) - defer ticker.Stop() + if interval <= 0 { + log.Ctx(ctx).Warn().Dur("interval", interval).Msg("health check poll interval must be positive, polling disabled") + return + } + + // nolint:gosec + // G404 use of non cryptographically secure random number generator is not a concern here, + // as it's used for jittering the interval for health checks. + rng := rand.New(rand.NewSource(time.Now().UnixNano())) + + // Reusable timer - avoids allocating a new channel on each tick + halfInterval := int64(interval) / 2 + jitter := time.Duration(rng.Int63n(int64(interval)) - halfInterval) + timer := time.NewTimer(interval + jitter) + defer timer.Stop() + for { select { case <-ctx.Done(): return - case <-ticker.C: + case <-timer.C: + // Reset timer for next tick before tryConnect so timer runs concurrently + jitter = time.Duration(rng.Int63n(int64(interval)) - halfInterval) + timer.Reset(interval + jitter) t.tryConnect(interval) } }