Skip to content

feat(core): add per-worker resilience and HTTP pool config types - #799

Merged
CatherineSue merged 1 commit into
mainfrom
feat/per-worker-resilience-types
Mar 18, 2026
Merged

CatherineSue merged 1 commit into
mainfrom
feat/per-worker-resilience-types

Conversation

@CatherineSue

@CatherineSue CatherineSue commented Mar 18, 2026 •

Copy link
Copy Markdown
Member

Description

Problem

The model gateway has global retry, circuit breaker, and HTTP client config — all workers share the same settings. Workers cannot have per-worker overrides for resilience behavior or connection pools, creating implicit coupling and preventing fine-grained tuning.

Solution

Add foundational config types for per-worker resilience. Protocol layer gets flat optional config types (HttpPoolConfig, ResilienceUpdate) following the existing HealthCheckUpdate PATCH-style pattern. Runtime layer resolves them against router defaults at worker creation time via ResolvedResilience. A per-worker HTTP client builder isolates connection pools per worker.

This is the first PR in the per-worker resilience refactor series — types only, no behavior changes, fully backwards compatible.

Changes

  • Add HttpPoolConfig and ResilienceUpdate structs to WorkerSpec in the protocol layer (crates/protocols/src/worker.rs)
  • Add ResolvedResilience struct and resolve_resilience() function in model_gateway/src/core/resilience.rs
  • Add build_worker_http_client() utility in model_gateway/src/core/http_client.rs
  • Register new modules and public exports in model_gateway/src/core/mod.rs

Test Plan

  • cargo test -p openai-protocol — all 36 tests pass (no regressions)
  • cargo test -p smg --lib core::resilience — 7 new tests covering default resolution, retry/CB overrides, disable flags, custom retryable codes
  • cargo test -p smg --lib core::http_client — 2 new tests for default and overridden client construction
  • cargo test -p smg --lib — all 435 tests pass, 0 failures
Checklist
  • cargo +nightly fmt passes
  • cargo clippy --all-targets --all-features -- -D warnings passes
  • (Optional) Documentation updated
  • (Optional) Please join us on Slack #sig-smg to discuss, review, and merge PRs

Summary by CodeRabbit

Add foundational types for per-worker resilience configuration:

- `HttpPoolConfig` and `ResilienceUpdate` in protocol layer (WorkerSpec)
  following the existing `HealthCheckUpdate` PATCH-style pattern
- `ResolvedResilience` in model_gateway for merging router defaults
  with per-worker overrides at worker construction time
- `build_worker_http_client()` for constructing isolated per-worker
  HTTP clients with TLS support from RouterConfig

Signed-off-by: Chang Su <chang.s.su@oracle.com>
@github-actions github-actions Bot added the model-gateway Model gateway crate changes label Mar 18, 2026
@coderabbitai

coderabbitai Bot commented Mar 18, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR extends the worker configuration system with per-worker HTTP pool and resilience settings. New HttpPoolConfig and ResilienceUpdate types in the protocols crate allow workers to override router-level defaults. The model_gateway implements a client builder and resilience resolver that merge these per-worker overrides with base configurations.

Changes

Cohort / File(s) Summary
Protocol Types
crates/protocols/src/worker.rs
Added HttpPoolConfig (pool settings) and ResilienceUpdate (retry and circuit breaker overrides) public structs with is_empty() checks. Extended WorkerSpec with http_pool and resilience fields initialized to defaults.
HTTP Client Builder
model_gateway/src/core/http_client.rs
Introduced build_worker_http_client() function to construct per-worker reqwest clients by merging HttpPoolConfig overrides with router-level TLS and timeout defaults, including PEM-based certificate/identity handling.
Resilience Module
model_gateway/src/core/resilience.rs
Added resolve_resilience() function to merge retry and circuit breaker overrides from ResilienceUpdate with base configs, producing ResolvedResilience. Defined DEFAULT_RETRYABLE_STATUS_CODES constant.
Module Exports
model_gateway/src/core/mod.rs
Exposed new http_client and resilience modules with public re-exports of build_worker_http_client, resolve_resilience, ResolvedResilience, and DEFAULT_RETRYABLE_STATUS_CODES.

Sequence Diagram(s)

sequenceDiagram
    participant WS as WorkerSpec
    participant HC as HTTP Client Builder
    participant RC as Resilience Config
    participant C as Client
    participant RR as ResolvedResilience

    WS->>HC: http_pool: HttpPoolConfig
    WS->>RC: resilience: ResilienceUpdate
    
    HC->>HC: Merge HttpPoolConfig<br/>with RouterConfig defaults
    HC->>HC: Apply TLS certificates<br/>(if configured)
    HC->>C: Build reqwest::Client
    
    RC->>RR: resolve_resilience(<br/>overrides)
    RR->>RR: Merge retry settings<br/>with base config
    RR->>RR: Merge circuit breaker<br/>with base config
    RR->>RR: Compute enabled flags
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

protocols, model-gateway

Suggested reviewers

  • key4ng
  • slin1237

Poem

🐰 A nimble rabbit hops with glee,
Per-worker configs, wild and free!
Pool settings dance, resilience flows,
Overrides merge where default goes.
Build, resolve, and carry on—
Configuration's here, the defaults gone! 🎯

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(core): add per-worker resilience and HTTP pool config types' accurately and concisely describes the main changes in the pull request.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ 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/per-worker-resilience-types
📝 Coding Plan
  • Generate coding plan for human review comments

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

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request lays the groundwork for enhanced configurability within the system by introducing new data structures and utility functions. It enables future capabilities for individual workers to define their own HTTP connection pooling and resilience parameters, such as retry mechanisms and circuit breaker settings, overriding global router defaults. The changes are purely structural and additive, ensuring backward compatibility and setting the stage for more granular control over worker behavior.

Highlights

  • New Configuration Types: Added HttpPoolConfig and ResilienceUpdate structs to the WorkerSpec in the protocol layer, allowing for per-worker HTTP connection pool and resilience overrides.
  • Resilience Resolution Logic: Introduced ResolvedResilience struct and resolve_resilience() function in model_gateway to merge router-level default resilience settings with per-worker overrides during worker construction.
  • Per-Worker HTTP Client Utility: Created build_worker_http_client() utility to construct isolated HTTP clients for each worker, incorporating TLS support and per-worker HTTP pool configurations.
  • Foundational Changes: This pull request is the initial step in a larger per-worker resilience refactor, focusing solely on adding foundational types and utilities without introducing immediate behavioral changes.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces foundational types for per-worker resilience and HTTP pool configuration, including HttpPoolConfig and ResilienceUpdate. It also adds utility functions to build per-worker HTTP clients and resolve resilience settings by merging router-level defaults with worker-specific overrides. The changes are well-structured and include good test coverage. My review includes a suggestion to enhance the flexibility of timeout configurations by allowing them to be disabled, which would be a valuable addition. This approach aligns with best practices for using Option in builder patterns.

Comment thread crates/protocols/src/worker.rs
Comment thread model_gateway/src/core/http_client.rs

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 17638fa900

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +52 to +62
max_retries: overrides.max_retries.unwrap_or(base_retry.max_retries),
initial_backoff_ms: overrides
.initial_backoff_ms
.unwrap_or(base_retry.initial_backoff_ms),
max_backoff_ms: overrides
.max_backoff_ms
.unwrap_or(base_retry.max_backoff_ms),
backoff_multiplier: overrides
.backoff_multiplier
.unwrap_or(base_retry.backoff_multiplier),
jitter_factor: overrides.jitter_factor.unwrap_or(base_retry.jitter_factor),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor router-wide retry disable in resolved config

When base_retry_enabled is false and the worker leaves disable_retry unset, this still copies base_retry.max_retries into resolved.retry. The existing retry path only consumes a RetryConfig (RouterConfig::effective_retry_config() in model_gateway/src/config/types.rs disables retries by forcing max_retries = 1, and routers pass that config straight into RetryExecutor), so wiring resolved.retry into the current router/worker stack will silently re-enable retries for deployments that set disable_retries: true unless every call site remembers to special-case retry_enabled.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Not an issue. The caller passes base_retry from RouterConfig::effective_retry_config(), which already sets max_retries = 1 when disable_retries: true. Additionally, the upcoming execute_with_resilience (next PR in the series) checks retry_enabled before entering the retry loop — that flag is the gatekeeper, not max_retries. The two mechanisms are complementary by design.

Comment thread model_gateway/src/core/resilience.rs

@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.

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 `@model_gateway/src/core/resilience.rs`:
- Around line 42-49: The resolve_resilience function currently uses
DEFAULT_RETRYABLE_STATUS_CODES when overrides.retry.retryable_status_codes is
None, which bypasses the router-level default; update resolve_resilience so that
when ResilienceUpdate (overrides) has retry.retryable_status_codes == None it
uses base_retry.retryable_status_codes.clone() (the router default) instead of
DEFAULT_RETRYABLE_STATUS_CODES, and only fall back to
DEFAULT_RETRYABLE_STATUS_CODES if both override and base_retry have no value;
apply the same fix wherever the code currently defaults straight to
DEFAULT_RETRYABLE_STATUS_CODES (e.g., the retry handling around
retryable_status_codes) so router defaults are respected (refer to function
resolve_resilience, type RetryConfig, and field retryable_status_codes).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 50be1a06-b8f7-4114-9155-319e9d366555

📥 Commits

Reviewing files that changed from the base of the PR and between c62672b and 17638fa.

📒 Files selected for processing (4)
  • crates/protocols/src/worker.rs
  • model_gateway/src/core/http_client.rs
  • model_gateway/src/core/mod.rs
  • model_gateway/src/core/resilience.rs

Comment thread model_gateway/src/core/resilience.rs
@CatherineSue
CatherineSue merged commit ebdf26b into main Mar 18, 2026
62 of 64 checks passed
@CatherineSue
CatherineSue deleted the feat/per-worker-resilience-types branch March 18, 2026 05:03
smfirmin pushed a commit to smfirmin/smg that referenced this pull request Mar 20, 2026
smfirmin pushed a commit to smfirmin/smg that referenced this pull request Mar 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

model-gateway Model gateway crate changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants