Skip to content

✨ Add ExtraDialOpts field to GRPCDialer - #230

Merged
openshift-merge-bot[bot] merged 1 commit into
open-cluster-management-io:mainfrom
kuudori:extra-dial-opts
Jun 30, 2026
Merged

✨ Add ExtraDialOpts field to GRPCDialer#230
openshift-merge-bot[bot] merged 1 commit into
open-cluster-management-io:mainfrom
kuudori:extra-dial-opts

Conversation

@kuudori

@kuudori kuudori commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Add ExtraDialOpts []grpc.DialOption field to GRPCDialer, allowing consumers to pass additional gRPC dial options that GRPCDialer does not configure directly (e.g. grpc.WithConnectParams, grpc.WithAuthority).

Options are appended last in Dial() — both TLS and insecure code paths — so caller-supplied options take precedence on conflict. Zero value (nil) preserves existing behavior.

Use case: configuring grpc.WithConnectParams to cap connection-level reconnect backoff (grpc-go defaults to MaxDelay=120s, which causes multi-minute recovery delays after server restarts).

Related issue(s)

N/A — additive feature, no breaking changes.

Summary by CodeRabbit

  • New Features
    • Added support for passing custom gRPC dial settings when connecting.
    • Improved flexibility for gRPC connections by allowing additional connection options to be supplied.
  • Tests
    • Added coverage for connecting with and without custom gRPC dial settings.

Allow consumers to pass additional grpc.DialOption values
(e.g. grpc.WithConnectParams, grpc.WithAuthority) that
GRPCDialer does not configure directly.

Options are appended last in Dial() so they take precedence
on conflict. Zero value preserves existing behavior.

Signed-off-by: Dmitrii Andreev <dandreev@redhat.com>
@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Adds an ExtraDialOpts []grpc.DialOption field to GRPCDialer. The Dial() method appends these options in both the TLS and insecure dial paths before calling grpc.NewClient. A new table-driven test TestDialExtraDialOpts validates the behavior with and without extra options set.

Changes

ExtraDialOpts support in GRPCDialer

Layer / File(s) Summary
ExtraDialOpts field, dial integration, and tests
pkg/cloudevents/generic/options/grpc/options.go, pkg/cloudevents/generic/options/grpc/options_test.go
GRPCDialer gains ExtraDialOpts []grpc.DialOption; Dial() appends them in both the TLS and insecure code paths. TestDialExtraDialOpts covers cases with grpc.WithConnectParams and with no extra options.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~5 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 The title is concise and accurately describes the main change to GRPCDialer.
Description check ✅ Passed The description follows the template well, with Summary and Related issue(s) sections filled in.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Warning

⚠️ This pull request shows signs of AI-generated slop (trivial_assertion). It has been flagged by CodeRabbit slop detection and should be reviewed carefully.

@kuudori
kuudori marked this pull request as ready for review June 29, 2026 15:47

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
pkg/cloudevents/generic/options/grpc/options_test.go (1)

123-165: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Strengthen this beyond a non-nil smoke test.

Line 149 leaves TLSConfig nil, so this only covers the insecure branch, and grpc.NewClient returning a non-nil connection does not verify that the extra option was actually applied. Please add at least one TLS case and one observable assertion for an injected option so the new contract is protected.

🤖 Prompt for 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.

In `@pkg/cloudevents/generic/options/grpc/options_test.go` around lines 123 - 165,
The current TestDialExtraDialOpts in GRPCDialer only checks that Dial() returns
a non-nil connection on the insecure path, so it doesn’t prove ExtraDialOpts are
applied or cover the TLS branch. Extend the test to include a TLSConfig-backed
case and add an observable assertion tied to an injected dial option (for
example by validating the dialer behavior changes when a known option is
supplied) so the contract in GRPCDialer.Dial is actually protected.
pkg/cloudevents/generic/options/grpc/options.go (1)

35-35: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Document that these options are forwarded to grpc.NewClient.

ExtraDialOpts accepts any grpc.DialOption, but this code passes them through grpc.NewClient, which does not honor the entire dial-option surface. A short field comment calling that out would prevent callers from assuming unsupported options will take effect.

🤖 Prompt for 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.

In `@pkg/cloudevents/generic/options/grpc/options.go` at line 35, Update the
`ExtraDialOpts` field comment in the `Options` type to explicitly say these
`grpc.DialOption` values are forwarded to `grpc.NewClient`, and that not every
dial option is supported or honored there. Keep the note short and colocated
with `ExtraDialOpts` so callers understand the limitation when using
`grpc.NewClient`.
🤖 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.

Nitpick comments:
In `@pkg/cloudevents/generic/options/grpc/options_test.go`:
- Around line 123-165: The current TestDialExtraDialOpts in GRPCDialer only
checks that Dial() returns a non-nil connection on the insecure path, so it
doesn’t prove ExtraDialOpts are applied or cover the TLS branch. Extend the test
to include a TLSConfig-backed case and add an observable assertion tied to an
injected dial option (for example by validating the dialer behavior changes when
a known option is supplied) so the contract in GRPCDialer.Dial is actually
protected.

In `@pkg/cloudevents/generic/options/grpc/options.go`:
- Line 35: Update the `ExtraDialOpts` field comment in the `Options` type to
explicitly say these `grpc.DialOption` values are forwarded to `grpc.NewClient`,
and that not every dial option is supported or honored there. Keep the note
short and colocated with `ExtraDialOpts` so callers understand the limitation
when using `grpc.NewClient`.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 873f54bc-b2d4-4374-8d8d-975d8311c547

📥 Commits

Reviewing files that changed from the base of the PR and between 5ba402e and 741d341.

📒 Files selected for processing (2)
  • pkg/cloudevents/generic/options/grpc/options.go
  • pkg/cloudevents/generic/options/grpc/options_test.go

@tesshuflower

Copy link
Copy Markdown
Contributor

/approve
/lgtm

@kuudori

kuudori commented Jun 29, 2026

Copy link
Copy Markdown
Contributor Author

/assign @tesshuflower

@kuudori kuudori closed this Jun 29, 2026
@kuudori kuudori reopened this Jun 29, 2026
@tesshuflower

Copy link
Copy Markdown
Contributor

@qiujian16 This looks pretty self-contained to me, but I don't seem to be able to approve - would you mind taking a look?

@qiujian16

Copy link
Copy Markdown
Member

/approve
/lgtm

@openshift-ci

openshift-ci Bot commented Jun 30, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: kuudori, qiujian16, tesshuflower

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:
  • OWNERS [qiujian16,tesshuflower]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@qiujian16

Copy link
Copy Markdown
Member

this is weird. I think your id is in the owner list

@openshift-merge-bot
openshift-merge-bot Bot merged commit ac9666c into open-cluster-management-io:main Jun 30, 2026
9 checks passed
openshift-merge-bot Bot added a commit to openshift-hyperfleet/hyperfleet-adapter that referenced this pull request Jul 7, 2026
…overy (#219)

## What

Fix ~95s gRPC recovery delay after Maestro restart. Three changes:

1. **Cap gRPC reconnect backoff at 5s** — configure
`grpc.WithConnectParams` via new `ExtraDialOpts` field on OCM SDK's
`GRPCDialer` ([upstream PR
merged](open-cluster-management-io/sdk-go#230)).
Reduces worst-case reconnect delay from 120s to 5s.

2. **Bounded retry for transient gRPC errors** — retry
`Create`/`Get`/`Patch` ManifestWork calls up to 3 times with exponential
backoff (1s, 2s, 4s) on `codes.Unavailable`. Uses
`k8s.io/apimachinery/pkg/util/wait.ExponentialBackoffWithContext`. Retry
wraps raw `workClient` calls inside each method (before
`apperrors.MaestroError` wraps the error, preserving gRPC status codes).

3. **Log warnings in AlwaysAck** — structured warning with event ID,
type, and error details before discarding errors. Makes silent publish
failures visible in adapter logs.

## Why

Maestro restart causes gRPC connection to enter `TRANSIENT_FAILURE` with
grpc-go default `MaxDelay=120s`. HTTP path recovers instantly
(per-request), but gRPC publish path stays in backoff. The adapter
silently drops every failed publish via `AlwaysAck`, so operators see
"no progress" instead of "Maestro publish failing". Breaks tier2-nightly
`maestro_unavailability` recovery test (120s window).

## Testing

- Unit tests for `isTransientGRPCError` (6 cases) and
`retryOnTransientGRPC` (5 scenarios: success, retry-success,
max-attempts, non-transient-fast-fail, context-cancellation)
- All existing `AlwaysAck` tests updated for new logger parameter
- `make test` + `make lint` pass

## Test plan

- [ ] `make test` — unit tests pass
- [ ] `make lint` — 0 issues
- [ ] `make build` — binary builds
- [ ] Verify tier2-nightly `maestro_unavailability` test passes 5x
consistently
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants