Skip to content

feat: add sane defaults for gRPC connection keepalive#72

Closed
ankurs wants to merge 4 commits intomainfrom
feat/keepalive-defaults
Closed

feat: add sane defaults for gRPC connection keepalive#72
ankurs wants to merge 4 commits intomainfrom
feat/keepalive-defaults

Conversation

@ankurs
Copy link
Copy Markdown
Member

@ankurs ankurs commented Apr 8, 2026

Summary

  • Set default values for gRPC connection keepalive: idle (300s), age (1800s), grace (30s)
  • Previously all defaulted to 0 (infinite), causing load balancing skew, slow rolling deployments, and stale DNS
  • Use -1 to opt out and restore infinite lifetime for any parameter (outer condition changed from > 0 to != 0)
  • Bump Go from 1.25.8 to 1.25.9 to fix stdlib CVEs (crypto/tls, net/http, os/exec, html/template)

Test plan

  • All existing tests pass with -race
  • New tests: TestGetGRPCServerOptions_WithEnvconfigDefaults, KeepaliveDisabledWithNegativeOne, KeepaliveMixed, KeepaliveAllZero
  • make lint clean, govulncheck clean (after Go 1.25.9 bump)
  • Verify in staging that connections rotate as expected
  • Verify -1 opt-out preserves infinite behavior

Summary by CodeRabbit

  • New Features

    • Added default gRPC server keepalive timeouts (300s idle, 1800s max age, 30s grace). Can be customized via environment variables or disabled with -1.
  • Bug Fixes

    • Keepalive options are now considered whenever keepalive fields are non-zero, ensuring non-positive overrides affect option construction.
  • Documentation

    • Updated configuration docs and API reference anchors to reflect new defaults.
  • Tests

    • Expanded tests for keepalive combinations and baseline option behavior.
  • Chores

    • Bumped Go toolchain version.

Set default values for connection idle (300s), age (1800s), and grace
(30s) to prevent indefinite connection lifetimes that cause load
balancing skew, slow rolling deployments, and stale DNS. Use -1 to
opt out and restore infinite lifetime for any parameter.
Copilot AI review requested due to automatic review settings April 8, 2026 04:55
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 8, 2026

📝 Walkthrough

Walkthrough

README anchors updated; three gRPC keepalive envconfig fields now have defaults (300/1800/30) and note -1 disables behavior; server option logic now appends keepalive params when any of those fields is non-zero; keepalive-focused tests added/adjusted; Go directive bumped to 1.25.9.

Changes

Cohort / File(s) Summary
Documentation Link Updates
README.md
Updated API reference line-anchor links to match shifted source line numbers; no signature or behavior changes.
gRPC Keepalive Config (docs & code)
config/README.md, config/config.go
Added default envconfig values for GRPCServerMaxConnectionIdleInSeconds (300), GRPCServerMaxConnectionAgeInSeconds (1800), GRPCServerMaxConnectionAgeGraceInSeconds (30); comments updated to state -1 disables each behavior.
Keepalive Parameter Logic
core.go
Changed keepalive-enablement check to use != 0 to decide appending ServerParameters; individual duration fields still applied only when > 0.
Keepalive Tests
core_coverage_test.go
Replaced simple length assertion with baseline-relative tests covering defaults, all -1, mixed, and all-zero keepalive scenarios; added helper testKeepaliveBaseline() and updated ConfigureInterceptors test call.
Tooling
go.mod
Bumped Go version directive from go 1.25.8 to go 1.25.9.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • vestor
  • fajran
  • kevinjom

Poem

🐰 I nibbled lines and tuned the tune,
Defaults set beneath the moon.
-1 whispers silence, non-zero hums,
Tests now dance where baseline thrums.
Hop, ship, and may the builds be smooth.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding default values for gRPC connection keepalive parameters to replace infinite defaults.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/keepalive-defaults

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds default gRPC server connection keepalive lifetimes (idle/age/grace) to encourage periodic connection rotation, improving load balancing behavior and reducing issues from long-lived/stale connections.

Changes:

  • Set env-driven defaults for GRPCServerMaxConnection*InSeconds (300s idle, 1800s age, 30s grace) and document -1 as an opt-out to “infinite”.
  • Update gRPC server option construction to apply keepalive params when any keepalive field is non-zero (enabling the -1 sentinel behavior).
  • Add/adjust tests around keepalive option selection.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
README.md Updates generated doc links/line references.
core.go Changes keepalive option gating logic from > 0 to != 0.
core_coverage_test.go Adds new keepalive-related tests and adjusts existing default test behavior.
config/README.md Documents new defaults and -1 opt-out for keepalive config fields.
config/config.go Adds envconfig defaults and updates comments for keepalive-related config fields.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread core_coverage_test.go
Comment thread core_coverage_test.go
Comment thread core_coverage_test.go Outdated
Comment thread core_coverage_test.go Outdated
ankurs added 2 commits April 8, 2026 13:04
Compare option count against all-zero baseline instead of hardcoded
thresholds, so tests fail if keepalive params are not actually appended.
Rename TestGetGRPCServerOptions_Default to _WithEnvconfigDefaults to
clarify it tests the envconfig default values, not zero-value config.
Fixes govulncheck failures for GO-2026-4860 (crypto/tls),
GO-2026-4861 (net/http), GO-2026-4862 (os/exec), GO-2026-4865
(html/template).
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread core_coverage_test.go
Comment thread go.mod
Eliminates tautological assertion by comparing all-zero config against
a positive-value config, proving zero actually omits keepalive option.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@core_coverage_test.go`:
- Around line 1371-1373: The test calls ConfigureInterceptors with five
arguments but the current ConfigureInterceptors function (named
ConfigureInterceptors) only accepts four; either remove the trailing 60 from the
TestConfigureInterceptors_BothBranches call or update ConfigureInterceptors's
signature to accept a timeout parameter and thread that new parameter through
its implementation (e.g., add a timeout int/uint param to ConfigureInterceptors
and update any call sites and internal uses). Locate the ConfigureInterceptors
function and either align the test to its existing four-arg signature or add the
fifth timeout argument to the function and its callers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8a2c84d7-5803-4425-a052-ab1152381366

📥 Commits

Reviewing files that changed from the base of the PR and between b42b9cd and 5b61b39.

📒 Files selected for processing (1)
  • core_coverage_test.go

Comment thread core_coverage_test.go
Comment on lines 1371 to 1373
func TestConfigureInterceptors_BothBranches(t *testing.T) {
ConfigureInterceptors(true, "X-My-Trace", "info", false)
ConfigureInterceptors(true, "X-My-Trace", "info", false, 60)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix the ConfigureInterceptors call signature.

Line 1372 passes five arguments, but ConfigureInterceptors in initializers.go currently accepts four, so this test does not compile. If the extra timeout is intentional, the matching signature change needs to land in the same PR; otherwise, drop the trailing 60.

Suggested fix
 func TestConfigureInterceptors_BothBranches(t *testing.T) {
-	ConfigureInterceptors(true, "X-My-Trace", "info", false, 60)
+	ConfigureInterceptors(true, "X-My-Trace", "info", false)
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func TestConfigureInterceptors_BothBranches(t *testing.T) {
ConfigureInterceptors(true, "X-My-Trace", "info", false)
ConfigureInterceptors(true, "X-My-Trace", "info", false, 60)
}
func TestConfigureInterceptors_BothBranches(t *testing.T) {
ConfigureInterceptors(true, "X-My-Trace", "info", false)
}
🧰 Tools
🪛 GitHub Actions: Go

[error] 1372-1372: golangci-lint build/test failure: too many arguments in call to ConfigureInterceptors in core_coverage_test.go:1372:59.

🪛 GitHub Check: lint

[failure] 1372-1372:
too many arguments in call to ConfigureInterceptors

🪛 GitHub Check: test

[failure] 1372-1372:
too many arguments in call to ConfigureInterceptors

🪛 golangci-lint (2.11.4)

[error] 1372-1372: too many arguments in call to ConfigureInterceptors

(typecheck)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@core_coverage_test.go` around lines 1371 - 1373, The test calls
ConfigureInterceptors with five arguments but the current ConfigureInterceptors
function (named ConfigureInterceptors) only accepts four; either remove the
trailing 60 from the TestConfigureInterceptors_BothBranches call or update
ConfigureInterceptors's signature to accept a timeout parameter and thread that
new parameter through its implementation (e.g., add a timeout int/uint param to
ConfigureInterceptors and update any call sites and internal uses). Locate the
ConfigureInterceptors function and either align the test to its existing
four-arg signature or add the fifth timeout argument to the function and its
callers.

@ankurs
Copy link
Copy Markdown
Member Author

ankurs commented Apr 8, 2026

Superseded by #73 which includes these keepalive changes alongside the default timeout config.

@ankurs ankurs closed this Apr 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants