Skip to content

feat(rest-api): dispatch every Flow endpoint through the gRPC proxy - #4706

Draft
kunzhao-nv wants to merge 7 commits into
NVIDIA:mainfrom
kunzhao-nv:feat/flow-proxy-taskrun-handlers
Draft

feat(rest-api): dispatch every Flow endpoint through the gRPC proxy#4706
kunzhao-nv wants to merge 7 commits into
NVIDIA:mainfrom
kunzhao-nv:feat/flow-proxy-taskrun-handlers

Conversation

@kunzhao-nv

@kunzhao-nv kunzhao-nv commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Every REST endpoint backed by on-site Flow had its own Temporal workflow and activity pair: 26 workflow types whose bodies were all the same single-activity pass-through, each needing its own registration on the site agent. This switches all of them to the generic Flow gRPC proxy added in #4560, so a new Flow endpoint no longer needs a workflow, an activity, and an agent release to reach the site.

Description

  • Migrates all 29 cloud-side call sites (26 workflow types) to ExecuteFlowGRPC: the run, rack, tray, task, and task-rule handlers, plus the shared ExecutePowerControlWorkflow, ExecuteBringUpRackWorkflow, and ExecuteFirmwareUpdateWorkflow helpers, which together cover the power, bring-up, and firmware endpoints. Nothing under api/ still submits a bespoke Flow workflow type.
  • Namespaces every derived workflow ID under flow-grpc-. The parameter-derivation rules are unchanged, but the resulting string has to differ: a deterministic ID plus USE_EXISTING attaches to whichever execution already holds that name, and the bespoke workflows are still registered during the rollout, so a collision would hand the proxy a payload it cannot decode.
  • Adds common.FlowWorkflowID and common.ProxyFlowGRPC so all five handler files share the namespacing and dispatch instead of repeating them. resolveTrayIDsBySlot is not a handler and returns a plain error, so it calls ExecuteFlowGRPC directly.
  • Leaves the bespoke workflows, activities, and their site-agent registrations in place; retiring them is a separate release.

Related issues

Closes #4271. Builds on #4560.

Type of Change

  • Add - New feature or capability
  • Change - Changes in existing functionality
  • Fix - Bug fixes
  • Remove - Removed features or deprecated functionality
  • Internal - Internal changes (refactoring, tests, docs, etc.)

Breaking Changes

  • This PR contains breaking changes

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • No testing required (docs, internal refactor, etc.)

Additional Notes

The eight Run endpoints now call ExecuteFlowGRPC instead of a bespoke
workflow per method. Derived workflow IDs keep their parameter rules but
move under a flow-grpc- namespace, so a proxy request cannot attach to a
bespoke execution of the same derived name; those workflows stay
registered on the site agent until a later release retires them.

The shared proxy allows the activity a single attempt, so these calls no
longer get the second attempt the bespoke Run workflows permitted.

Signed-off-by: Kun Zhao <kunzhao@nvidia.com>
@kunzhao-nv
kunzhao-nv requested a review from a team as a code owner August 7, 2026 17:29
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 26e75fb0-b8bc-4e63-8e0f-a2167b6983af

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Summary by CodeRabbit

  • Improvements

    • Task Run operations now follow a consistent Flow-based execution path.
    • Creation, retrieval, listing, targeting, and lifecycle actions use more predictable workflow handling.
    • API responses now provide clearer feedback for Flow errors and timeouts.
    • Task Run processing remains available during timeout conditions without unnecessary termination.
  • Documentation

    • Updated migration and rollout guidance for endpoint processing, timeout behavior, and retry changes.

Walkthrough

TaskRun handlers now proxy Flow gRPC calls through ExecuteFlowGRPC. The change adds namespaced workflow IDs, shared error handling, deterministic lifecycle dispatch, proxy-based tests, and updated migration guidance.

Changes

TaskRun Flow proxy migration

Layer / File(s) Summary
Shared Flow proxy and workflow IDs
rest-api/api/pkg/api/handler/taskrun.go
The handler adds namespaced workflow IDs and shared ExecuteFlowGRPC response and error handling. Timeout handling no longer terminates proxy executions.
TaskRun endpoint dispatch
rest-api/api/pkg/api/handler/taskrun.go
Create, get, list, target-list, pause, resume, advance, and cancel operations dispatch through Flow methods. Create uses a fresh workflow ID. Other operations use deterministic IDs and conflict policies.
Proxy behavior validation and migration guidance
rest-api/api/pkg/api/handler/taskrun_test.go, rest-api/skills/rest-flow-grpc-proxy/SKILL.md
Tests validate serialized proxy responses, method dispatch, workflow IDs, conflict policies, and includeStats. The migration guide records timeout, retry, and endpoint registration behavior.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 The description clearly explains the migration of Flow-backed REST endpoints to the generic gRPC proxy.
Title check ✅ Passed The title clearly and concisely identifies the main change: routing all Flow endpoints through the gRPC proxy.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

🔐 TruffleHog Secret Scan

No secrets or credentials found!

Your code has been scanned for 700+ types of secrets and credentials. All clear! 🎉

🔗 View scan details

🕐 Last updated: 2026-08-07 23:00:26 UTC | Commit: d329e5b

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

🧹 Nitpick comments (2)
rest-api/api/pkg/api/handler/taskrun_test.go (2)

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

Cover every deterministic workflow-ID input.

The tests do not verify all inputs that prevent incompatible requests from coalescing. A regression in includeStats handling, query hashing, transport namespacing, or conflict policy can pass these tests.

  • rest-api/api/pkg/api/handler/taskrun_test.go#L316-L322: add a successful includeStats=true case and assert its distinct flow-grpc-task-run-get-...-true ID.
  • rest-api/api/pkg/api/handler/taskrun_test.go#L404-L409: capture StartWorkflowOptions and assert the namespaced, query-derived list ID and USE_EXISTING policy.
  • rest-api/api/pkg/api/handler/taskrun_test.go#L520-L525: capture StartWorkflowOptions and assert the namespaced, run-and-query-derived target-list ID and USE_EXISTING policy.
🤖 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 `@rest-api/api/pkg/api/handler/taskrun_test.go` around lines 316 - 322, Expand
the task-run workflow-ID tests to cover every deterministic input: in
rest-api/api/pkg/api/handler/taskrun_test.go:316-322 add a successful
includeStats=true case asserting its distinct flow-grpc-task-run-get-...-true
ID; at :404-409 capture StartWorkflowOptions and assert the namespaced,
query-derived list ID with USE_EXISTING; at :520-525 capture
StartWorkflowOptions and assert the namespaced, run-and-query-derived
target-list ID with USE_EXISTING.

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

Assert the proxied Flow method in the mock.

testRunProxyDispatch matches the grpcproxy.Request argument with mock.Anything, so tests can pass when a handler supplies the wrong FullMethod. Pass the expected method to the helper and match grpcproxy.Request.FullMethod against the endpoint's flowv1.Flow_*_FullMethodName.

🤖 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 `@rest-api/api/pkg/api/handler/taskrun_test.go` around lines 70 - 76, Update
testRunProxyDispatch to accept the expected Flow method and replace the
grpcproxy.Request mock.Anything matcher with an assertion that
Request.FullMethod equals the corresponding flowv1.Flow_*_FullMethodName for
each endpoint. Update all helper call sites to pass the appropriate expected
method while preserving the existing workflow-start capture and error behavior.
🤖 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 `@rest-api/api/pkg/api/handler/taskrun_test.go`:
- Around line 316-322: Expand the task-run workflow-ID tests to cover every
deterministic input: in rest-api/api/pkg/api/handler/taskrun_test.go:316-322 add
a successful includeStats=true case asserting its distinct
flow-grpc-task-run-get-...-true ID; at :404-409 capture StartWorkflowOptions and
assert the namespaced, query-derived list ID with USE_EXISTING; at :520-525
capture StartWorkflowOptions and assert the namespaced, run-and-query-derived
target-list ID with USE_EXISTING.
- Around line 70-76: Update testRunProxyDispatch to accept the expected Flow
method and replace the grpcproxy.Request mock.Anything matcher with an assertion
that Request.FullMethod equals the corresponding flowv1.Flow_*_FullMethodName
for each endpoint. Update all helper call sites to pass the appropriate expected
method while preserving the existing workflow-start capture and error behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 73f1f28a-a167-45de-9df8-14a8b3abbde4

📥 Commits

Reviewing files that changed from the base of the PR and between 9cc6a20 and 1a351a3.

📒 Files selected for processing (3)
  • rest-api/api/pkg/api/handler/taskrun.go
  • rest-api/api/pkg/api/handler/taskrun_test.go
  • rest-api/skills/rest-flow-grpc-proxy/SKILL.md

@thossain-nv thossain-nv added the rest-api Add this label when an issue or PR concerns NICo REST API label Aug 7, 2026 — with ChatGPT Codex Connector
The proxy's workflow timeout expires inside the caller's context budget,
so a timeout reaching the handler comes from an execution that already
closed itself. Terminating it failed and reported a data desync that had
not happened; the handler now returns the proxy's 504 unchanged.

Tests pin the Flow method each endpoint proxies, which the workflow ID
alone could not show, plus the derived IDs and conflict policies for the
list and target-list reads.

Signed-off-by: Kun Zhao <kunzhao@nvidia.com>
@kunzhao-nv
kunzhao-nv marked this pull request as draft August 7, 2026 23:01
@copy-pr-bot

copy-pr-bot Bot commented Aug 7, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

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

🧹 Nitpick comments (1)
rest-api/api/pkg/api/handler/taskrun_test.go (1)

67-82: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add a timeout response regression test.

The changed proxy contract returns 504 for a proxy timeout and does not call TerminateWorkflow. The shown failure cases only inject a generic scheduling error and expect 500.

Add a case that injects the proxy timeout condition, asserts 504, and asserts that TerminateWorkflow is not called. This protects the changed timeout behavior.

As per coding guidelines, follow the shared Engineering Guidelines for “verification expectations.”

🤖 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 `@rest-api/api/pkg/api/handler/taskrun_test.go` around lines 67 - 82, Add a
regression case to the existing proxy failure tests that injects the proxy
timeout condition, expects HTTP 504, and verifies TerminateWorkflow is not
called. Reuse the existing test helper and mock setup around
testRunProxyDispatch, preserving the current generic scheduling-error case and
its 500 expectation.

Source: Coding guidelines

🤖 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 `@rest-api/api/pkg/api/handler/taskrun_test.go`:
- Around line 67-82: Add a regression case to the existing proxy failure tests
that injects the proxy timeout condition, expects HTTP 504, and verifies
TerminateWorkflow is not called. Reuse the existing test helper and mock setup
around testRunProxyDispatch, preserving the current generic scheduling-error
case and its 500 expectation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 44f5ec16-f6dd-4c6c-8a82-1461868c4d2b

📥 Commits

Reviewing files that changed from the base of the PR and between 1a351a3 and d329e5b.

📒 Files selected for processing (3)
  • rest-api/api/pkg/api/handler/taskrun.go
  • rest-api/api/pkg/api/handler/taskrun_test.go
  • rest-api/skills/rest-flow-grpc-proxy/SKILL.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • rest-api/skills/rest-flow-grpc-proxy/SKILL.md

Extends the migration from the eight Run endpoints to all 26 Flow-backed
workflow types, reached from 29 call sites across the rack, tray, task,
task-rule, and run handlers plus the shared power, bring-up, and firmware
helpers. Each site keeps its own workflow ID derivation and conflict policy,
namespaced under flow-grpc- so a proxy request cannot attach to a bespoke
execution of the same derived name.

The tray get and list sites set only a reuse policy and leave the conflict
policy unspecified, so identical concurrent reads still do not coalesce there;
that asymmetry is carried over rather than normalized under cover of a
transport change.

Promotes the workflow-ID and dispatch helpers into common so all five handler
files share them, and drops the initializer clauses the Run migration
introduced.

Signed-off-by: Kun Zhao <kunzhao@nvidia.com>
@kunzhao-nv kunzhao-nv changed the title feat(rest-api): dispatch TaskRun endpoints through the Flow gRPC proxy feat(rest-api): dispatch every Flow endpoint through the gRPC proxy Aug 7, 2026
A DeadlineExceeded in the workflow result was read as proof the caller had
stopped waiting, but it can also come from inside a live execution. Only
wfCtx carries that evidence, and a Temporal timeout is the stronger signal
when both hold, so it is classified first. Neither case terminates the
execution: the activity does not heartbeat, so cancellation cannot reach an
in-flight Flow RPC, and freeing a deterministic ID would let a retry start a
duplicate mutation instead of attaching through USE_EXISTING.

A caller that goes away during the start now reports 504 rather than 500.

Signed-off-by: Kun Zhao <kunzhao@nvidia.com>
The power, bring-up and firmware helpers pick the Flow method themselves and
are the only route to it, so the handler tests matching any method left the
choice unverified. Assert the method, workflow ID, conflict policy and decoded
request per power state, including the Forced flag that is all that separates
force-off from off on the wire.

Signed-off-by: Kun Zhao <kunzhao@nvidia.com>
Routing these endpoints through the generic proxy changed their timeout
response from 500 to 504, which the spec did not describe. The shared
GatewayTimeoutError says what a client should do about it, since a timed-out
mutation may still be running at the site and a retry attaches to it.

Signed-off-by: Kun Zhao <kunzhao@nvidia.com>
Covers 24c060d.

Signed-off-by: Kun Zhao <kunzhao@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rest-api Add this label when an issue or PR concerns NICo REST API

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: create a generic FlowProxy for Flow-backed endpoints

2 participants