Skip to content

fix(worker): honor explicit worker connection schemes - #1484

Closed
heymrbox wants to merge 1 commit into
mainfrom
weiwei-dev
Closed

heymrbox wants to merge 1 commit into
mainfrom
weiwei-dev

Conversation

@heymrbox

@heymrbox heymrbox commented May 13, 2026 •

Copy link
Copy Markdown
Contributor
## Description

### Problem

Explicit worker URL schemes were not fully respected during local connection mode detection. A worker configured with `grpc://host:port` could still be probed over HTTP, and if the HTTP health check succeeded, the worker could be classified as `ConnectionMode::Http` despite the explicit gRPC scheme.

### Solution

Honor explicit URL schemes before falling back to auto-detection:

- `grpc://...` runs only the gRPC reachability check and sets `ConnectionMode::Grpc`
- `http://...` and `https://...` run only the HTTP reachability check and set `ConnectionMode::Http`
- bare `host:port` URLs keep the existing behavior of probing both protocols, with HTTP priority if both pass

## Changes

- Added explicit scheme classification for local worker connection detection.
- Short-circuited detection for explicit HTTP/gRPC worker URLs.
- Preserved existing auto-detection behavior for bare worker URLs.
- Added unit tests for explicit gRPC, explicit HTTP(S), and bare URL handling.

## Test Plan

Reproduced the issue by reviewing `DetectConnectionModeStep`: before this change, all URLs were passed into both HTTP and gRPC probes, so `grpc://...` could still be selected as HTTP when `/health` responded.

After this change, explicit schemes are handled before the auto-detection block, so `grpc://...` no longer falls through to HTTP probing.


<details>
<summary>Checklist</summary>

- [x] `cargo +nightly fmt` passes
- [x] `cargo clippy --all-targets --all-features -- -D warnings` passes
- [ ] (Optional) Documentation updated
- [ ] (Optional) Please join us on Slack [#sig-smg](https://slack.lightseek.org) to discuss, review, and merge PRs

</details>

Summary by CodeRabbit

  • Bug Fixes
    • Connection detection now respects explicit URL schemes (grpc://, http://, https://), performing targeted health checks for the specified protocol with clear error messages if the connection fails. Bare host:port URLs retain existing probing behavior.

Review Change Stack

Signed-off-by: Weiwei Zheng <heymrbox@gmail.com>
@github-actions github-actions Bot added the model-gateway Model gateway crate changes label May 13, 2026
@coderabbitai

coderabbitai Bot commented May 13, 2026 •

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0d490022-5646-43e3-9bd6-317298253ec3

📥 Commits

Reviewing files that changed from the base of the PR and between 401e666 and fddb01a.

📒 Files selected for processing (1)
  • model_gateway/src/workflow/steps/local/detect_connection.rs

📝 Walkthrough

Walkthrough

DetectConnectionModeStep now honors explicit URL schemes by parsing grpc://, http://, or https:// prefixes and performing only the corresponding health check. Bare URLs retain the existing parallel-probe-and-prefer-HTTP behavior. New helper and unit tests validate scheme parsing and fallback logic.

Changes

Explicit URL Scheme Support

Layer / File(s) Summary
Scheme detection helper and conditional execute logic
model_gateway/src/workflow/steps/local/detect_connection.rs
New explicit_connection_mode helper maps grpc:// to ConnectionMode::Grpc and http:///https:// to ConnectionMode::Http. Execute method branches on explicit schemes, running only the matching health check; on failure returns StepFailed scoped to the explicit protocol; on success sets context.data.connection_mode and returns Success. Bare URLs fall through to existing parallel HTTP and gRPC probing.
Scheme detection and fallback tests
model_gateway/src/workflow/steps/local/detect_connection.rs
Unit tests verify explicit_connection_mode parsing for grpc://, http://, https://, and bare host:port inputs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

model-gateway

Suggested reviewers

  • CatherineSue
  • slin1237

Poem

🐰 A rabbit hops through schemes with glee,
Now gRPC and HTTP both run free,
Explicit paths, no guessing game,
Connection modes honor their true name! 🌐

✨ 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 weiwei-dev

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

@github-actions

Copy link
Copy Markdown

Hi @heymrbox, the branch weiwei-dev does not follow our naming convention.

Please use one of the following formats:

  • <type>/<description> — e.g. feat/add-auth, fix/null-pointer, dependabot/cargo/pyo3-0.28.1
  • <username>/<description> — e.g. changsu/fix-routing

Allowed types: feat, fix, chore, docs, refactor, test, ci, perf

To fix, rename your branch locally, push the new branch, and open a new PR:

git branch -m <new-branch-name>
git push origin -u <new-branch-name>

@github-actions

Copy link
Copy Markdown

Closing this PR because the branch name weiwei-dev does not follow the naming convention.

@github-actions github-actions Bot closed this May 13, 2026
};

fn explicit_connection_mode(url: &str) -> Option<ConnectionMode> {
let normalized_url = url.to_ascii_lowercase();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Nit: to_ascii_lowercase() makes detection case-insensitive (e.g. GRPC://host is recognized), but the original mixed-case URL is then passed unchanged to try_grpc_reachable / try_http_reachable, which use case-sensitive starts_with("grpc://") / starts_with("https://") internally. For a URL like GRPC://localhost:30001, detection correctly picks gRPC, but try_grpc_reachable falls into its else branch and produces a malformed grpc://GRPC://localhost:30001.

Two options:

  1. Drop the to_ascii_lowercase() so detection is case-sensitive like downstream (simplest, mixed-case schemes are rare).
  2. Normalize the URL itself (lowercase the scheme portion) and pass the normalized URL to the probe functions.

Either way, the detection and the downstream consumers should agree on case handling.

@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 explicit connection mode detection by checking for URL schemes like grpc://, http://, and https:// before falling back to parallel protocol probing. It also includes unit tests for this new logic. Feedback suggests using a dedicated URL parsing library instead of string prefix matching for better robustness and case-sensitivity handling. Additionally, there is a recommendation to simplify the error message formatting to remove redundancy.

Comment on lines +66 to +70
if let Some(connection_mode) = explicit_connection_mode(&url) {
let result = match connection_mode {
ConnectionMode::Http => try_http_reachable(&url, timeout, client).await,
ConnectionMode::Grpc => try_grpc_reachable(&url, timeout).await,
};

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.

medium

The current implementation is susceptible to case-sensitivity issues because the underlying reachability probes perform case-sensitive prefix matching on the URL. To reliably handle schemes and distinguish between different URL types, parse the URL using a dedicated library and check its scheme instead of using string prefix matching. This approach avoids misclassifying URLs and ensures robustness against variations like 'GRPC://'.

References
  1. To reliably distinguish data URIs from other URLs, parse the URL and check its scheme instead of using string prefix matching. This avoids misclassifying relative URLs.

Comment on lines +82 to +92
let protocol = match connection_mode {
ConnectionMode::Http => "HTTP",
ConnectionMode::Grpc => "gRPC",
};
return Err(WorkflowError::StepFailed {
step_id: StepId::new("detect_connection_mode"),
message: format!(
"{protocol} health check failed for explicit {} worker URL {}: {}",
connection_mode, config.url, err
),
});

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.

medium

The error message is redundant, repeating "health check failed" and including both the capitalized protocol string and the connection_mode enum. Additionally, the underlying error err from the probe already includes a "Health check failed" prefix. A more concise message would improve log clarity.

Suggested change
let protocol = match connection_mode {
ConnectionMode::Http => "HTTP",
ConnectionMode::Grpc => "gRPC",
};
return Err(WorkflowError::StepFailed {
step_id: StepId::new("detect_connection_mode"),
message: format!(
"{protocol} health check failed for explicit {} worker URL {}: {}",
connection_mode, config.url, err
),
});
let protocol = match connection_mode {
ConnectionMode::Http => "HTTP",
ConnectionMode::Grpc => "gRPC",
};
return Err(WorkflowError::StepFailed {
step_id: StepId::new("detect_connection_mode"),
message: format!(
"Explicit {protocol} worker URL {} is unreachable: {err}",
config.url
),
});

@github-actions

Copy link
Copy Markdown

Hi @heymrbox, the branch weiwei-dev does not follow our naming convention.

Please use one of the following formats:

  • <type>/<description> — e.g. feat/add-auth, fix/null-pointer, dependabot/cargo/pyo3-0.28.1
  • <username>/<description> — e.g. changsu/fix-routing

Allowed types: feat, fix, chore, docs, refactor, test, ci, perf

To fix, rename your branch locally, push the new branch, and open a new PR:

git branch -m <new-branch-name>
git push origin -u <new-branch-name>

@lightseek-bot
lightseek-bot deleted the weiwei-dev branch May 13, 2026 06:29
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.

1 participant