Skip to content

chore: simplify, modernize (Go 1.26), update deps#147

Merged
rustatian merged 6 commits into
masterfrom
chore/cleanup-modernize-deps
May 31, 2026
Merged

chore: simplify, modernize (Go 1.26), update deps#147
rustatian merged 6 commits into
masterfrom
chore/cleanup-modernize-deps

Conversation

@rustatian
Copy link
Copy Markdown
Member

@rustatian rustatian commented May 29, 2026

Fixed

Bugs (R)

  • server.go: MaxConnectionAgeGrace was set from MaxConnectionAge (wrong field) — now uses MaxConnectionAgeGrace
  • plugin.go: Stop() called p.healthServer.SetServingStatus and Shutdown unconditionally, causing nil panic when Stop is called before Serve — guarded with nil check
  • plugin.go: Workers() returned nil on the first worker-state error, discarding all remaining workers — changed to continue
  • health_server.go: List() and Check() read h.status without holding h.mu — added mutex read
  • plugin.go: type switch to *static_pool.Pool to call Destroy was unnecessary — api.Pool interface exposes Destroy directly

Simplifications (S)

  • server.go: redundant grpc.UnaryServerInterceptor(p.interceptor) cast removed
  • server.go: errors.Str(fmt.Sprintf(...))errors.Errorf(...)
  • proxy/proxy.go: double-scan Contains+Split → single strings.Split with length guard
  • proxy/proxy.go: redundant phpCode < math.MaxUint32 check removed (ParseUint with bitSize=32 already guarantees it); math import dropped
  • php/keywords.go: isSpacerChar multi-case switch → strings.ContainsRune("_ :-", c)
  • php/keywords.go, php/ns.go: bytes.NewBuffer(nil) used as string builder → strings.Builder
  • php/template.go: template.Must(...).Parse(phpBody) called on every body() invocation → cached with sync.OnceValue

Modernizations (M)

  • config.go: os.IsNotExist(err) ×4 → errors.Is(err, os.ErrNotExist)
  • proxy/proxy.go: putPld nils Body/Context defeating pool preallocation → reslice [:0]
  • php/keywords.go: isReserved linear scan over 70 keywords → map[string]struct{} lookup
  • php/keywords.go: make([]rune, 0) reset in loop → word[:0]

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Fixed potential panic during graceful shutdown when service stops.
    • Resolved thread-safety issues in health status reporting.
    • Corrected MaxConnectionAgeGrace configuration to use proper value instead of incorrect fallback.
    • Improved error parsing in proxy layer for better error reporting.
  • Tests

    • Expanded test coverage for health server operations, metrics collection, and HTTP status endpoints.

- Fix MaxConnectionAgeGrace using wrong field (MaxConnectionAge) in keepalive params
- Guard healthServer nil in Stop() before Serve() is called
- Fix Workers() to skip erroring workers instead of dropping all remaining
- Add mutex reads in health_server List() and Check() to prevent data race
- Drop redundant UnaryServerInterceptor type cast; use errors.Errorf directly
- Replace os.IsNotExist with errors.Is(err, os.ErrNotExist) throughout config.go
- Eliminate static_pool import; call Destroy via the api.Pool interface
- proxy: single strings.Split replaces Contains+Split double-scan
- proxy: reslice Body/Context to [:0] in putPld to preserve pool allocations
- proxy: drop redundant phpCode < math.MaxUint32 check (ParseUint bitSize=32 guarantees it)
- php/keywords: replace linear isReserved scan with map lookup; isSpacerChar via ContainsRune
- php/keywords, php/ns: replace bytes.Buffer with strings.Builder
- php/template: cache parsed template with sync.OnceValue instead of re-parsing per call
Copilot AI review requested due to automatic review settings May 29, 2026 12:25
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 29, 2026

Review Change Stack

Warning

Review limit reached

@rustatian, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 24 minutes. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 773a49f5-bb58-4605-b78e-7ca26780692f

📥 Commits

Reviewing files that changed from the base of the PR and between 5aefc4e and f78cf64.

⛔ Files ignored due to path filters (1)
  • go.work.sum is excluded by !**/*.sum
📒 Files selected for processing (2)
  • config.go
  • metrics_test.go
📝 Walkthrough

Walkthrough

This PR addresses stability, testing, and code quality across the gRPC plugin. It fixes a critical nil-interface panic in plugin lifecycle, adds concurrency protection to health status reads, corrects server configuration bugs, modernizes error handling patterns, expands test coverage for health/metrics/status endpoints, and simplifies PHP code generation utilities.

Changes

gRPC Service Stability and Testing

Layer / File(s) Summary
Health server concurrency safety and tests
health_server.go, health_server_test.go
List and Check snapshot status under mutex to prevent unsynchronized access. Comprehensive tests validate initial NOT_SERVING state, shutdown freezing behavior, stream watch lifecycle with context cancellation, and health service registration.
Plugin lifecycle and pool safety
plugin.go
Serve assigns pool to local variable before storing in p.gPool to avoid nil-interface panics. Stop adds conditional nil checks for healthServer and server, and simplifies pool destruction with direct Destroy() call; comments explain the nil-interface hazard.
Server interceptor and keepalive configuration fixes
server.go
Unary interceptor appended directly without grpc.UnaryServerInterceptor wrapper. Interceptor not-found error uses errors.Errorf. MaxConnectionAgeGrace correctly reads from dedicated config field instead of MaxConnectionAge.
Error handling and error parsing modernization
config.go, proxy/proxy.go
config.go replaces deprecated os.IsNotExist with errors.Is(err, os.ErrNotExist) for proto, TLS, and RootCA file checks. proxy.go simplifies error delimiter parsing and removes redundant math.MaxUint32 guard; clarifies why pooled buffers are not resliced for reuse.
Metrics collection and dependency management
metrics_test.go, go.mod
Comprehensive Prometheus metrics tests validate descriptor count, gauge values for worker state/totals, and collector registry. Prometheus client_model promoted to direct dependency.
Plugin HTTP status endpoint tests
status_test.go
Tests for Plugin.Status() and Plugin.Ready() validate service unavailable when no workers, OK when ready workers present, and unavailable when only working (non-ready) workers exist.
Expanded root module test coverage
.github/workflows/linux.yml
go test now explicitly covers root module (.) alongside subdirectories for comprehensive codec, parser, protoc_plugins, and proxy package coverage.
PHP code generation refactoring
protoc_plugins/protoc-gen-php-grpc/php/keywords.go, protoc_plugins/protoc-gen-php-grpc/php/ns.go
Keyword helpers and namespace generator simplified using standard library: slices.Contains for membership, strings.Builder replacing bytes.Buffer, rune buffer reset via slice reslicing, strings.ContainsRune for character sets; unnecessary bytes import removed.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

bug

Suggested reviewers

  • wolfy-j

Poem

🐰 With mutex locks and pools so safe,
No panics at the shutdown gate.
Health checks true, with tests galore,
And metrics that we can adore.
PHP made neat—this PR's no bore! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.58% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title accurately describes the main changes: fixes, simplifications, and modernizations for Go 1.26 with dependency updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed PR description covers all required sections: reason (bug fixes and code improvements), detailed changes organized by category, and license acceptance statement provided.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/cleanup-modernize-deps

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

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

This PR modernizes and simplifies the RoadRunner gRPC plugin while fixing several lifecycle, health-check, and configuration handling issues.

Changes:

  • Corrects keepalive grace configuration and improves error construction.
  • Adds synchronization for health status reads and safer shutdown guards.
  • Modernizes proxy and PHP generator helpers with simplified parsing, builders, cached templates, and keyword lookup.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
server.go Simplifies interceptor setup and fixes MaxConnectionAgeGrace assignment.
proxy/proxy.go Simplifies error parsing and adjusts payload pool reset behavior.
protoc_plugins/protoc-gen-php-grpc/php/template.go Caches parsed PHP template and uses strings.Builder.
protoc_plugins/protoc-gen-php-grpc/php/ns.go Replaces buffer usage with strings.Builder.
protoc_plugins/protoc-gen-php-grpc/php/keywords.go Replaces keyword slice scan with map lookup and simplifies string building/splitting helpers.
plugin.go Guards health server shutdown paths and simplifies pool destruction.
health_server.go Adds locking around health status reads.
config.go Uses errors.Is for file-not-found checks.

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

Comment thread proxy/proxy.go Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented May 29, 2026

Codecov Report

❌ Patch coverage is 73.91304% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.56%. Comparing base (202b5d1) to head (f78cf64).

Files with missing lines Patch % Lines
config.go 0.00% 5 Missing ⚠️
server.go 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #147      +/-   ##
==========================================
+ Coverage   68.31%   77.56%   +9.24%     
==========================================
  Files           7        7              
  Lines         464      468       +4     
==========================================
+ Hits          317      363      +46     
+ Misses        113       79      -34     
+ Partials       34       26       -8     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

rustatian added 2 commits May 29, 2026 22:57
- keywords.go: use slices.Contains over the existing reservedKeywords slice
  instead of introducing a second package-level map (+nolint).
- template.go: revert to per-call template parse instead of a package-level
  sync.OnceValue global (this is a codegen path, per-call cost is irrelevant).
- Serve: NewPool returns a concrete *static_pool.Pool; on error it is a
  nil pointer. Assigning it straight to the api.Pool interface field made
  the interface non-nil while wrapping a nil pointer, so Stop's
  `p.gPool != nil` guard passed and Destroy dereferenced a nil receiver
  (panic). Assign p.gPool only after NewPool succeeds.
- proxy.putPld: makePayload always reassigns Body/Context to the
  per-request buffers, so reslicing to [:0] never reused the preallocated
  slices and pinned the request's backing arrays in the pooled object.
  Reset to nil so they can be collected (addresses review feedback).
- Workers: keep return-nil-on-error to stay consistent with the other RR
  plugins (http/tcp/centrifuge/temporal) instead of skipping bad workers.
@rustatian rustatian self-assigned this May 31, 2026
rustatian added 2 commits May 31, 2026 21:21
…I coverage

The root-package coverage step ran only ./codec ./parser ./protoc_plugins
./proxy, so root-package unit tests never counted toward codecov — root
coverage came solely from the PHP integration suite, which skips several
auxiliary surfaces.

Add white-box unit tests for the most-uncovered root files:
- status.go: Status/Ready over a fake api.Pool with workers driven into
  Ready/Working FSM states (0% -> 100%)
- metrics.go: StatsExporter Describe/Collect across all worker-state branches
  plus MetricsCollector, over a fake Informer (0% -> 100%)
- health_server.go: Check/List/Watch/SetServingStatus/Shutdown lifecycle via a
  minimal Health_WatchServer (0% -> ~95%)

Wire `.` into the root-module coverage step so these run in CI. Root-package
unit coverage rises 12.9% -> 37.1%; the codecov union gains the lines the
integration suite never exercises.

client_model becomes a direct dependency (metric-family assertions via dto).
Replace the manual channel-drain counter with assert.Len on the buffered
Describe channel (a /simplify pass finding). Behavior and coverage unchanged.
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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@config.go`:
- Around line 112-115: The error message for validating c.TLS.RootCA is wrong
and misleading; locate the branch that checks if os.Stat(c.TLS.RootCA) returns
os.ErrNotExist (the code that currently returns errors.Errorf("root ca path
provided, but key file '%s' does not exists", c.TLS.RootCA")) and change the
message to correctly reference the Root CA file and fix grammar (e.g. "root CA
file '%s' does not exist" or "root CA path provided, but root CA file '%s' does
not exist"), keeping the same error construction and using c.TLS.RootCA.
🪄 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: 86026694-68e1-4e7e-ba1c-526d0efd4e92

📥 Commits

Reviewing files that changed from the base of the PR and between 202b5d1 and 5aefc4e.

📒 Files selected for processing (12)
  • .github/workflows/linux.yml
  • config.go
  • go.mod
  • health_server.go
  • health_server_test.go
  • metrics_test.go
  • plugin.go
  • protoc_plugins/protoc-gen-php-grpc/php/keywords.go
  • protoc_plugins/protoc-gen-php-grpc/php/ns.go
  • proxy/proxy.go
  • server.go
  • status_test.go

Comment thread config.go Outdated
Signed-off-by: Valery Piashchynski <piashchynski.valery@gmail.com>
@rustatian rustatian merged commit c65181c into master May 31, 2026
10 checks passed
@rustatian rustatian deleted the chore/cleanup-modernize-deps branch May 31, 2026 20:01
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