Skip to content

fix(migration): make runs idempotently reattachable - #575

Draft
AprilNEA wants to merge 1 commit into
masterfrom
fix/migration-reattach
Draft

fix(migration): make runs idempotently reattachable#575
AprilNEA wants to merge 1 commit into
masterfrom
fix/migration-reattach

Conversation

@AprilNEA

@AprilNEA AprilNEA commented Aug 9, 2026

Copy link
Copy Markdown
Member

Summary

  • make RunMigration idempotently reattach to the same plan and options
  • replay the latest progress or terminal result without starting duplicate work
  • reject concurrent plans without consuming their prepared state
  • preserve CoreError::Common Connect status codes and stop abandoned stream bridges

Why

Desktop clients must be able to recover from a broken progress stream without duplicating a migration or treating an unknown result as complete. Missing plans now reach clients as NOT_FOUND, so a daemon restart is distinguishable from a transient transport failure.

Validation

  • devenv shell -- cargo fmt --check
  • devenv shell -- cargo clippy -p arcbox-core -p arcbox-api --all-targets -- -D warnings
  • devenv shell -- cargo test -p arcbox-core -p arcbox-api (18 + 4 + 189 tests passed)
  • devenv shell -- cargo build -p arcbox-protocol

@greptile-apps

greptile-apps Bot commented Aug 9, 2026

Copy link
Copy Markdown

Greptile Summary

The PR makes migration execution reattachable by retaining each run’s latest event or terminal result, serializing run startup, and preserving structured Connect error codes.

  • Replays retained migration state for repeated requests with matching options.
  • Rejects conflicting concurrent migrations without consuming prepared plans.
  • Maps nested core common errors to their corresponding Connect status codes.
  • Documents the reattachment behavior in the migration RPC contract.

Confidence Score: 4/5

The PR appears safe to merge, with a non-blocking issue where adjacent migration progress updates can be coalesced before reaching connected clients.

Reattachment and terminal-result replay remain intact, but using a single-value watch channel means the progress stream does not reliably deliver every emitted intermediate update.

Files Needing Attention: app/arcbox-core/src/migration/mod.rs

Important Files Changed

Filename Overview
app/arcbox-core/src/migration/mod.rs Adds serialized, retained migration runs and reattachment, but the single-value watch channel can coalesce progress emitted for connected subscribers.
app/arcbox-api/src/connect/migration.rs Routes streamed core errors through the standard API-to-Connect error mapping.
app/arcbox-api/src/error.rs Preserves Connect status codes for CommonError values nested inside CoreError.
rpc/arcbox-protocol/proto/api.proto Documents that repeated migration requests attach to the existing run and replay its latest state.

Sequence Diagram

sequenceDiagram
    participant Client
    participant API as Migration API
    participant Manager as MigrationManager
    participant Run as MigrationRun/watch
    participant Executor

    Client->>API: RunMigration(plan_id, options)
    API->>Manager: run_migration(request)
    alt Matching run exists
        Manager->>Run: subscribe()
        Run-->>Client: latest progress or terminal result
    else Another plan is active
        Manager-->>Client: FailedPrecondition
    else Prepared plan exists
        Manager->>Run: create retained run
        Manager->>Executor: execute(plan, options)
        loop Migration progress
            Executor->>Run: publish(event)
            Run-->>Client: latest observed event
        end
        Executor->>Run: publish(terminal result)
        Run-->>Client: terminal result
    end
Loading

Reviews (1): Last reviewed commit: "fix(migration): make runs idempotently r..." | Re-trigger Greptile

}

fn publish(&self, event: RunMigrationEvent) {
self.events.send_replace(Some(event));

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 Watch coalesces progress events

send_replace retains only the latest value, so when another progress or terminal event is published before the subscriber bridge observes the preceding update, connected clients omit that intermediate resource or phase update and their progress displays jump over work that occurred.

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.

1 participant