Skip to content

Add support for broker client-go qps and burst config#1272

Merged
tpantelis merged 7 commits intosubmariner-io:develfrom
msft-paddy14:users/padgupta/add_rate_limit_config
Feb 16, 2026
Merged

Add support for broker client-go qps and burst config#1272
tpantelis merged 7 commits intosubmariner-io:develfrom
msft-paddy14:users/padgupta/add_rate_limit_config

Conversation

@msft-paddy14
Copy link
Contributor

@msft-paddy14 msft-paddy14 commented Feb 12, 2026

Adds support for configuring client-go QPS and Burst settings via environment variables for the broker syncer component.
Addresses: #1271
When syncing resources between the local cluster and broker, the broker syncer can experience client-side throttling.

The environment variables apply to both the local cluster client and the broker cluster client created by the broker syncer in ensureClients().

Add support for configuring client-go QPS and Burst via environment variables:

  • BROKER_K8S_QPS: Maximum queries per second to the API server (default: 5)
  • BROKER_K8S_BURST: Maximum burst for throttle to the API server (default: 10)

Summary by CodeRabbit

  • New Features

    • Broker client request pacing via QPS/Burst configurable (explicit broker settings take precedence).
    • New configuration keys added for Kubernetes client QPS/Burst (including broker-specific keys).
  • Tests

    • Added tests validating QPS/Burst propagation, precedence between broker and global config, and defaults.
  • Bug Fixes

    • Clarified error message to reference broker environment configuration.

@submariner-bot
Copy link
Contributor

🤖 Created branch: z_pr1272/msft-paddy14/users/padgupta/add_rate_limit_config

@coderabbitai
Copy link

coderabbitai bot commented Feb 12, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds propagation of global QPS/Burst into broker and local Kubernetes REST configs via a new applyQPSBurst helper; reorders Insecure in brokerSpecification and updates an env-processing error message; adds global QPS/Burst constants; tests updated to verify QPS/Burst application and precedence.

Changes

Cohort / File(s) Summary
Broker configuration
pkg/syncer/broker/config.go
Reordered the Insecure bool field within brokerSpecification and changed an error message to "error processing broker env configuration".
Broker syncer implementation
pkg/syncer/broker/syncer.go
Added applyQPSBurst(restConfig *rest.Config) and invoke it after obtaining BrokerRestConfig to copy QPS/Burst from global config; set BrokerNamespace from spec when creating client; nil-check retained.
Broker syncer tests
pkg/syncer/broker/syncer_test.go
Initialize/reset global config in tests, capture actual rest.Configs used, and add assertions verifying QPS/Burst propagation and precedence between explicit REST config values and global settings.
Global config
pkg/global/config.go
Added exported constants: K8sClientQPS, K8sClientBurst, K8sBrokerClientQPS, K8sBrokerClientBurst for global QPS/Burst keys.

Sequence Diagram(s)

sequenceDiagram
    participant Test
    participant Syncer
    participant GlobalCfg
    participant RESTConfig
    participant K8sClient

    Test->>GlobalCfg: Init()/set K8sClientQPS/Burst (or unset)
    Test->>Syncer: Create broker client (may provide explicit REST configs)
    Syncer->>RESTConfig: obtain or build BrokerRestConfig
    Syncer->>GlobalCfg: read K8sBrokerClientQPS / K8sBrokerClientBurst
    alt BrokerRestConfig has explicit QPS/Burst
        RESTConfig-->>Syncer: keep explicit QPS/Burst
    else explicit values absent
        Syncer->>RESTConfig: applyQPSBurst -> set QPS/Burst from GlobalCfg
    end
    Syncer->>K8sClient: create client using BrokerRestConfig
    K8sClient-->>Test: client uses applied QPS/Burst
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (9 files):

⚔️ .github/dependabot.yml (content)
⚔️ .github/workflows/linting.yml (content)
⚔️ .github/workflows/report.yml (content)
⚔️ go.mod (content)
⚔️ go.sum (content)
⚔️ pkg/global/config.go (content)
⚔️ pkg/syncer/broker/config.go (content)
⚔️ pkg/syncer/broker/syncer.go (content)
⚔️ pkg/syncer/broker/syncer_test.go (content)

These conflicts must be resolved before merging into devel.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately describes the main objective of the PR: adding broker client-go QPS and Burst configuration support.
Actionable Comments Resolved ✅ Passed All actionable comments (TODO, FIXME, XXX, HACK, BUG, REVISIT, DEPRECATED) have been resolved in modified files.

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


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.

@msft-paddy14 msft-paddy14 changed the title add support for broker/client qps and burst config Add support for broker/client qps and burst config Feb 12, 2026
@msft-paddy14 msft-paddy14 changed the title Add support for broker/client qps and burst config Add support for broker client-go qps and burst config Feb 12, 2026
Add BROKER_K8S_QPS and BROKER_K8S_BURST environment variables to
configure client-go rate limiting for both local and broker REST
clients. Defaults are QPS=5 and Burst=10.

Changes:
- Add QPS and Burst fields to brokerSpecification struct
- Apply settings to both LocalRestConfig and BrokerRestConfig
- Add unit tests for custom and default values

Signed-off-by: Paddy <padgupta@microsoft.com>
@msft-paddy14 msft-paddy14 force-pushed the users/padgupta/add_rate_limit_config branch from 9904ade to e518085 Compare February 12, 2026 08:43
@msft-paddy14 msft-paddy14 marked this pull request as ready for review February 12, 2026 08:48
Copy link

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/syncer/broker/syncer.go (1)

387-394: ⚠️ Potential issue | 🔴 Critical

Bug: QPS/Burst settings are applied to BrokerRestConfig after the broker dynamic client is already created, so they have no effect.

createBrokerClient() (line 388) calls resource.NewDynamicClient(c.BrokerRestConfig) internally (line 356), which reads QPS and Burst at client-creation time to configure the rate limiter. applyQPSBurst at line 394 mutates the config after the client is built, so the broker client will use the default rate limits instead of the configured ones.

Move applyQPSBurst for the broker config into createBrokerClient, just before the NewDynamicClient call:

Proposed fix

In createBrokerClient, apply QPS/Burst before creating the client. One approach — pass the spec into createBrokerClient and apply there:

-func (c *SyncerConfig) createBrokerClient() error {
+func (c *SyncerConfig) createBrokerClient(brokerSpec *brokerSpecification) error {
 	_, gvr, e := util.ToUnstructuredResource(c.ResourceConfigs[0].BrokerResourceType, c.RestMapper)
 	if e != nil {
 		return e //nolint:wrapcheck // OK to return the error as is.
@@ // ... existing broker config setup ...
 
+	applyQPSBurst(c.BrokerRestConfig, brokerSpec)
+
 	c.BrokerClient, err = resource.NewDynamicClient(c.BrokerRestConfig)
 
 	return errors.Wrap(err, "error creating dynamic client")
 }

And in ensureClients, update the call site and remove the post-hoc apply:

 	if c.BrokerClient == nil {
-		if err := c.createBrokerClient(); err != nil {
+		if err := c.createBrokerClient(brokerSpec); err != nil {
 			return err
 		}
+	} else {
+		applyQPSBurst(c.BrokerRestConfig, brokerSpec)
 	}
 
-	// Apply QPS and Burst settings to broker REST config
-	applyQPSBurst(c.BrokerRestConfig, brokerSpec)
-
 	return nil
🤖 Fix all issues with AI agents
In `@pkg/syncer/broker/syncer_test.go`:
- Around line 730-735: The test currently asserts on actualBrokerRestConfig
after creation but doesn't verify the rest config as seen by the client at
creation time; move the assertions for actualBrokerRestConfig (QPS and Burst)
into the mock/generator callback that intercepts broker client creation so you
assert the config parameter passed into the client factory there (the same place
you already verify LocalRestConfig), e.g., inside the mock callback that
receives the rest.Config used to create the broker client; assert QPS ==
float32(5) and Burst == 10 on that config instead of only checking the captured
variable later.
- Around line 708-713: The test currently captures a pointer to
config.BrokerRestConfig (actualBrokerRestConfig = inConfig) so mutations after
client creation hide the ordering bug; update the mock for NewDynamicClient
(resourceutils.NewDynamicClient or dynamic.NewForConfig replacement in the test)
to capture and assert inConfig.QPS and inConfig.Burst at call time (inside the
mock) for the broker branch, and keep the existing post-creation assertions for
completeness; this ensures applyQPSBurst must set QPS/Burst before
NewDynamicClient is invoked (refer to symbols:
NewDynamicClient/resourceutils.NewDynamicClient, applyQPSBurst,
config.BrokerRestConfig, actualBrokerRestConfig).
🧹 Nitpick comments (1)
pkg/syncer/broker/syncer.go (1)

364-368: getBrokerSpecification() is called twice — once here and once inside createBrokerClient() (line 324).

When BrokerClient is nil and BrokerRestConfig is nil, both calls execute and parse the same environment variables. If you adopt the fix above (passing brokerSpec into createBrokerClient), you can reuse the same spec inside createBrokerClient and eliminate the duplicate call at line 324.

}

// Apply QPS and Burst settings to local REST config
applyQPSBurst(c.LocalRestConfig, brokerSpec)
Copy link
Contributor

Choose a reason for hiding this comment

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

The caller creates and provides the LocalRestConfig so the caller should configure the rate limiter settings and this component shouldn't set them as a side effect. Same with the BrokerRestConfig, if provided by the caller.

This component should only configure the rate limiter settings for the BrokerRestConfig if it creates it via the env variables (ie in createBrokerClient after line 345).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense. Addressed the changes.

Signed-off-by: Paddy <padgupta@microsoft.com>
@msft-paddy14 msft-paddy14 force-pushed the users/padgupta/add_rate_limit_config branch from 8d70cd1 to bd956d6 Compare February 12, 2026 15:25
Signed-off-by: Paddy <padgupta@microsoft.com>
Signed-off-by: Paddy <padgupta@microsoft.com>
Copy link

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/syncer/broker/syncer.go (1)

362-386: ⚠️ Potential issue | 🟠 Major

QPS/Burst not applied to the local cluster client.

The PR description states the settings "apply to both the local cluster client and the broker cluster client," but applyQPSBurst is only called for BrokerRestConfig (line 346). The local client created at line 373 from LocalRestConfig does not get QPS/Burst applied. If this is intentional (e.g., local config is always caller-provided), please update the PR description; otherwise, add the call here too.

Proposed fix if local client should also get QPS/Burst
 	if c.LocalClient == nil {
+		applyQPSBurst(c.LocalRestConfig)
 		c.LocalClient, err = resource.NewDynamicClient(c.LocalRestConfig)
 		if err != nil {
 			return errors.Wrap(err, "error creating dynamic client")
 		}
 	}
🤖 Fix all issues with AI agents
In `@pkg/global/config.go`:
- Around line 35-38: Rename the two constants from K8S_CLIENT_QPS and
K8S_CLIENT_BURST to follow the project's MixedCaps style: K8sClientQPS and
K8sClientBurst; update every reference to these constants (search for
K8S_CLIENT_QPS and K8S_CLIENT_BURST) to use the new names (e.g., in any config
lookups or settings), and run go build/tests to ensure there are no remaining
references or import issues.
🧹 Nitpick comments (2)
pkg/syncer/broker/syncer.go (1)

388-400: applyQPSBurst silently treats 0 as "not configured" — intentional zero values are impossible.

Using 0 as the sentinel means a caller cannot explicitly set QPS or Burst to 0 via global config. For QPS this is unlikely to matter, but it's worth documenting or considering a different sentinel (e.g., negative value, or a separate "is set" check).

pkg/syncer/broker/syncer_test.go (1)

714-729: Consider asserting QPS/Burst inside the mock to guard against ordering regressions.

The assertions at lines 726-727 check actualBrokerRestConfig after syncer creation. Since actualBrokerRestConfig is a captured pointer, it will reflect mutations made both before and after NewDynamicClient. If applyQPSBurst were accidentally moved after NewDynamicClient in production code, this test would still pass (pointer sees the final state) but the real client wouldn't get the configured rate limits. Asserting inside the mock callback would catch this.

Proposed inline assertion in the mock
 resourceutils.NewDynamicClient = func(inConfig *rest.Config) (dynamic.Interface, error) {
     if equality.Semantic.DeepDerivative(inConfig, config.LocalRestConfig) {
         return localDynClient, nil
     } else if equality.Semantic.DeepDerivative(inConfig, config.BrokerRestConfig) ||
         (brokerAPIServer != "" && strings.HasSuffix(inConfig.Host, brokerAPIServer)) {
         actualBrokerRestConfig = inConfig
+        // Verify QPS/Burst are set at client-creation time
+        if qps := global.Get(global.K8S_CLIENT_QPS, 0); qps != 0 {
+            Expect(inConfig.QPS).To(Equal(float32(qps)))
+        }
+        if burst := global.Get(global.K8S_CLIENT_BURST, 0); burst != 0 {
+            Expect(inConfig.Burst).To(Equal(burst))
+        }
         return brokerDynClient, nil
     }

Signed-off-by: Paddy <padgupta@microsoft.com>
Signed-off-by: Paddy <padgupta@microsoft.com>
@tpantelis tpantelis merged commit 7bb4db8 into submariner-io:devel Feb 16, 2026
19 checks passed
@submariner-bot
Copy link
Contributor

🤖 Closed branches: [z_pr1272/msft-paddy14/users/padgupta/add_rate_limit_config]

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.

4 participants

Comments