Skip to content

feat(spider-huntsman): Complete storage gRPC server: - #356

Closed
sitaowang1998 wants to merge 14 commits into
y-scope:mainfrom
sitaowang1998:proto-fix
Closed

feat(spider-huntsman): Complete storage gRPC server:#356
sitaowang1998 wants to merge 14 commits into
y-scope:mainfrom
sitaowang1998:proto-fix

Conversation

@sitaowang1998

@sitaowang1998 sitaowang1998 commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Description

Use gRPC status instead of custom error code

Replace remaining error codes in gRPC protocol (InboundQueueResponseError, ResourceGroupManagementError, ExecutionManagerLivenessError, SchedulerRegistrationError) with status.

Update scheduler and execution manager clients to parse gRPC status into local error type.

Add delete resource group implementation

Adds resource group deletion in database and in cache. This also removes all jobs belonging to this resource group from both database and cache.

Warning

Because of the limitation in the scheduler queue implementation, enqueued tasks owned by the resource group are not removed. However, the scheduled task should later fail at task instance creation.
There is known possible race condition between the deletion and another task instance creation. However, the task should fail later when reporting result, with no extra action needed by storage.

Add ResendReadyTasks

As pointed out in #352, ResendReadyTasks is now put into InboundQueueService.

Checklist

  • The PR satisfies the contribution guidelines.
  • This is a breaking change and that has been indicated in the PR title, OR this isn't a
    breaking change.
  • Necessary docs have been updated, OR no docs need to be updated.

Validation performed

  • GitHub workflows pass.

Summary by CodeRabbit

  • New Features
    • Added support for deleting resource groups, including removing associated cached jobs.
    • Added an inbound-queue RPC to resend ready tasks (and scheduler client support for it).
    • Expanded scheduler support with registration and listing of schedulers.
  • Bug Fixes
    • Treat “job gone” and missing-job scenarios as benign no-ops during task registration and outcome reporting.
    • Improved gRPC status/error mapping and updated response parsing for simplified service responses.
  • Tests
    • Updated and extended unit/integration coverage for new response shapes, mappings, and resend/delete behaviors.

@sitaowang1998
sitaowang1998 requested a review from a team as a code owner June 25, 2026 06:08
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c097d12c-d290-47a8-ad22-680728d1ea1f

📥 Commits

Reviewing files that changed from the base of the PR and between fb3e023 and 16a139d.

📒 Files selected for processing (3)
  • components/spider-execution-manager/src/client/grpc/liveness.rs
  • components/spider-scheduler/src/storage_client/grpc.rs
  • components/spider-storage/src/grpc.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • components/spider-storage/src/grpc.rs
  • components/spider-execution-manager/src/client/grpc/liveness.rs
  • components/spider-scheduler/src/storage_client/grpc.rs

Walkthrough

The PR updates proto contracts, storage-side gRPC handling, resource-group deletion, execution-manager liveness parsing, and scheduler resend support. It also adds JobGone handling and new unpacking/conversion paths.

Changes

Storage control-flow updates

Layer / File(s) Summary
Proto shapes and unpackers
components/spider-proto/storage/storage.proto, components/spider-proto-rust/src/lib.rs, components/spider-proto-rust/src/scheduler.rs, components/spider-proto-rust/src/unpack/storage.rs
storage.proto replaces several oneof result responses with direct payload fields, adds ResendReadyTasks, and the proto-rust crate adds scheduler conversion plus unpackers for the new request messages.
Resource-group deletion
components/spider-storage/src/cache/job.rs, components/spider-storage/src/db/mariadb.rs, components/spider-storage/src/state/job_cache.rs, components/spider-storage/src/state/service.rs, components/spider-storage/tests/mariadb_test.rs
SharedJobControlBlock exposes resource-group ownership, JobCache can evict jobs by resource group, and ServiceState::delete_resource_group verifies the password, deletes the DB row, then removes cached jobs.
Storage gRPC handlers
components/spider-storage/src/state.rs, components/spider-storage/src/state/test_utils.rs, components/spider-storage/src/grpc.rs
The storage gRPC adapter centralizes status mapping, implements inbound-queue/resource-group/liveness/scheduler/session RPCs, builds ReadyTasks responses from ready-queue entries, and updates scheduler-registration test scaffolding.
Liveness client parsing
components/spider-execution-manager/src/client/grpc/liveness.rs
GrpcLivenessClient maps tonic status codes through map_liveness_status and parses the new registration and session_id response fields.
JobGone handling
components/spider-execution-manager/src/client/storage.rs, components/spider-execution-manager/src/client/grpc/storage.rs, components/spider-execution-manager/src/runtime.rs
StorageResponseError::JobGone is added, the storage gRPC client maps NOT_FOUND to it, and task registration/reporting treat JobGone as a benign no-op.
Scheduler resend client
components/spider-scheduler/src/storage_client/mod.rs, components/spider-scheduler/src/storage_client/grpc.rs, components/spider-scheduler/src/error.rs, components/spider-scheduler/src/core_impl/round_robin/tests.rs
SchedulerStorageClient gains resend_ready_tasks, inbound RPC failures map through map_inbound_status, PollReadyTasksResponse.tasks is parsed directly, and the mock/test coverage follows the new RPC.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • y-scope/spider#323: Introduced the resource-group delete API that this PR extends with cached-job eviction and delete-path tests.
  • y-scope/spider#340: Added the execution-manager liveness client that this PR updates for the new registration and heartbeat response shapes.
  • y-scope/spider#347: Added the scheduler registration protocol and storage-side scheduler support that this PR extends with the new scheduler client and resend flow.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR includes many unrelated changes beyond the ResendReadyTasks move, including resource-group deletion, error mapping refactors, and scheduler/execution-manager updates. Split the unrelated refactors into separate PRs and keep this change focused on the ResendReadyTasks service move and client/server wiring.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and matches the main change: completing storage gRPC server support.
Linked Issues check ✅ Passed ResendReadyTasks is moved to a scheduler-facing service, the server implements it, and the scheduler client now calls the new RPC.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

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

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
components/spider-proto/storage/storage.proto (1)

152-165: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Reserve the retired protobuf tags before this schema moves forward.

This PR removes wire fields (session_id plus several response error variants) but does not reserve their numbers/names. That leaves those tags reusable in a later edit, which is how old bytes start decoding as the wrong field.

Also applies to: 181-214, 242-244

🤖 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 `@components/spider-proto/storage/storage.proto` around lines 152 - 165,
Reserve the retired protobuf field numbers and names in the affected message
definitions in storage.proto so they cannot be reused later. Update the relevant
messages around ResourceGroupIdResponse, VerifyResourceGroupRequest,
DeleteResourceGroupRequest, and the other referenced response/schema blocks to
add reserved tags/names for the removed session_id and deleted error variants,
keeping the proto schema forward-safe.
🤖 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.

Inline comments:
In `@components/spider-execution-manager/src/client/grpc/liveness.rs`:
- Around line 108-119: The `register_response_to_result` helper currently
accepts a zero `session_id`, unlike `heartbeat_response_to_result`, so add the
same validation there and reject `registration.session_id == 0` with a
`LivenessResponseError::Transport` before building `RegistrationResponse`. Keep
the check alongside the existing `registration` extraction in
`register_response_to_result` so both response paths enforce the same nonzero
session-id rule.

In `@components/spider-scheduler/src/storage_client/grpc.rs`:
- Around line 132-145: The status mapping in map_inbound_status currently treats
every Code::Unavailable as StorageClientError::InboundClosed, which conflates
real queue փակ signals with transient transport failures. Update the match logic
in map_inbound_status to detect the server’s closed marker via status.message()
(for example, a “queue closed” substring) or switch the closed-state RPCs to a
distinct code like FAILED_PRECONDITION, and only return
StorageClientError::InboundClosed for that explicit closed signal. Keep generic
Unavailable errors mapped to StorageClientError::Server so poll_* and
resend_ready_tasks can still retry them.

In `@components/spider-storage/src/grpc.rs`:
- Line 1050: The test fixture in GrpcLivenessClient-related gRPC tests uses
TEST_SESSION_ID with a zero value, but the client contract rejects zero for
registration and heartbeat responses. Update TEST_SESSION_ID to a non-zero
SessionId in grpc.rs so the tests exercise a valid wire value and stay aligned
with the GrpcLivenessClient behavior.

In `@components/spider-storage/src/state/service.rs`:
- Around line 557-568: Serialize delete_resource_group against concurrent
register_job by adding per-resource-group coordination or a tombstone check so
late cache inserts are blocked after deletion. Update delete_resource_group and
the register_job flow around self.inner.db.delete,
self.inner.job_cache.remove_by_resource_group, and job_cache.insert so a
resource group marked deleted cannot be reinserted into cache after the DB row
is removed, and ensure create_task_instance cannot serve work from a deleted
group.

---

Nitpick comments:
In `@components/spider-proto/storage/storage.proto`:
- Around line 152-165: Reserve the retired protobuf field numbers and names in
the affected message definitions in storage.proto so they cannot be reused
later. Update the relevant messages around ResourceGroupIdResponse,
VerifyResourceGroupRequest, DeleteResourceGroupRequest, and the other referenced
response/schema blocks to add reserved tags/names for the removed session_id and
deleted error variants, keeping the proto schema forward-safe.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0e0fa444-a6da-4970-9717-f38c031556d0

📥 Commits

Reviewing files that changed from the base of the PR and between dfc8d5f and fb3e023.

⛔ Files ignored due to path filters (1)
  • components/spider-proto-rust/src/generated/storage.rs is excluded by !**/generated/**
📒 Files selected for processing (20)
  • components/spider-execution-manager/src/client/grpc/liveness.rs
  • components/spider-execution-manager/src/client/grpc/storage.rs
  • components/spider-execution-manager/src/client/storage.rs
  • components/spider-execution-manager/src/runtime.rs
  • components/spider-proto-rust/src/lib.rs
  • components/spider-proto-rust/src/scheduler.rs
  • components/spider-proto-rust/src/unpack/storage.rs
  • components/spider-proto/storage/storage.proto
  • components/spider-scheduler/src/core_impl/round_robin/tests.rs
  • components/spider-scheduler/src/error.rs
  • components/spider-scheduler/src/storage_client/grpc.rs
  • components/spider-scheduler/src/storage_client/mod.rs
  • components/spider-storage/src/cache/job.rs
  • components/spider-storage/src/db/mariadb.rs
  • components/spider-storage/src/grpc.rs
  • components/spider-storage/src/state.rs
  • components/spider-storage/src/state/job_cache.rs
  • components/spider-storage/src/state/service.rs
  • components/spider-storage/src/state/test_utils.rs
  • components/spider-storage/tests/mariadb_test.rs
💤 Files with no reviewable changes (1)
  • components/spider-scheduler/src/error.rs

Comment thread components/spider-execution-manager/src/client/grpc/liveness.rs Outdated
Comment on lines +132 to 145
/// Maps a [`tonic::Status`] returned by an inbound-queue RPC into a [`StorageClientError`].
///
/// # Returns
///
/// * [`StorageClientError::InboundClosed`] when the inbound queue is closed, signalled by
/// `UNAVAILABLE`.
/// * [`StorageClientError::InvalidInput`] for a malformed request, signalled by `INVALID_ARGUMENT`.
/// * [`StorageClientError::Server`] for any other failure.
fn map_inbound_status(status: &tonic::Status) -> StorageClientError {
match status.code() {
Code::Unavailable => StorageClientError::InboundClosed,
Code::InvalidArgument => to_invalid_input_error(status.message()),
_ => StorageClientError::Server(status.message().to_owned()),
}

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.

🩺 Stability & Availability | 🟠 Major

Don't treat every UNAVAILABLE as InboundClosed

tonic::Status uses Code::Unavailable for both server-side queue closures and transient transport/network failures. Mapping all Unavailable errors to StorageClientError::InboundClosed causes the scheduler to incorrectly treat temporary outages as permanent lane closures across poll_* and resend_ready_tasks.

Distinguish the server's closed signal from client-side Unavailable errors by checking status.message() (e.g., for a "queue closed" substring) or using a distinct gRPC code like FAILED_PRECONDITION for the closed state. Transient Unavailable errors should remain on the transport path to allow for retries.

🤖 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 `@components/spider-scheduler/src/storage_client/grpc.rs` around lines 132 -
145, The status mapping in map_inbound_status currently treats every
Code::Unavailable as StorageClientError::InboundClosed, which conflates real
queue փակ signals with transient transport failures. Update the match logic in
map_inbound_status to detect the server’s closed marker via status.message()
(for example, a “queue closed” substring) or switch the closed-state RPCs to a
distinct code like FAILED_PRECONDITION, and only return
StorageClientError::InboundClosed for that explicit closed signal. Keep generic
Unavailable errors mapped to StorageClientError::Server so poll_* and
resend_ready_tasks can still retry them.

Comment thread components/spider-storage/src/grpc.rs Outdated
Comment on lines +557 to +568
pub async fn delete_resource_group(
&self,
resource_group_id: ResourceGroupId,
password: &[u8],
) -> Result<(), StorageServerError> {
self.inner.db.verify(resource_group_id, password).await?;
self.inner.db.delete(resource_group_id).await?;
let evicted_jobs = self
.inner
.job_cache
.remove_by_resource_group(resource_group_id)
.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.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Serialize deletion against in-flight job registration.

register_job writes the DB row before it inserts the JCB into cache. If a registration commits before Line 563 and only reaches job_cache.insert(...) after Line 568, this method returns success with the MariaDB rows gone but a live cached job still present. create_task_instance then continues serving work from cache for a resource group that was already deleted.

Please add per-resource-group coordination or a tombstone/check that prevents late cache insertion after deletion.

🤖 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 `@components/spider-storage/src/state/service.rs` around lines 557 - 568,
Serialize delete_resource_group against concurrent register_job by adding
per-resource-group coordination or a tombstone check so late cache inserts are
blocked after deletion. Update delete_resource_group and the register_job flow
around self.inner.db.delete, self.inner.job_cache.remove_by_resource_group, and
job_cache.insert so a resource group marked deleted cannot be reinserted into
cache after the DB row is removed, and ensure create_task_instance cannot serve
work from a deleted group.

@sitaowang1998

Copy link
Copy Markdown
Collaborator Author

Closed as too large. Will split into separate pr.

@sitaowang1998
sitaowang1998 deleted the proto-fix branch June 26, 2026 19:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move ResendReadyTasks RPC to a dedicated scheduler-facing service

1 participant