Files
seaweedfs/sw-block/design/v2-second-migration-task-pack.md
T
pingqiuandClaude Opus 4.6 11c6aaf316 feat: Batch 7 + Phase 16C-E — command dispatch extraction + engine refinements
Batch 7: Command dispatch binding extraction
- New weed/server/blockcmd package: CommandHandler interface + DispatchCommands
- volume_server_block.go applyCoreCommandsWithAssignment delegates to dispatcher
- weed/server still owns RecordCommand, EmitCoreEvent, PublishProjection
- v2bridge NOT given command-switch or event-emission semantics

Phase 16C: Rebuilding assignment enters core command path
Phase 16D: Rebuild recovery-task startup is command-driven
Phase 16E: Catch-up recovery-task startup is command-driven

Engine refinements:
- RecoveryTarget on AssignmentDelivered event
- shouldStartRecoveryTask / shouldStartReceiver guards
- bootstrapReason: awaiting_rebuild_start

Bridge/contract updates:
- control_adapter.go: refined translation helpers
- contract.go: executor port alignment

Migration design docs (Batch 1-3 delivered, design artifacts):
- v2-first/second/third-migration-batch.md + task-pack.md
- v2-assignment-translation-unification.md
- v2-execution-muscles-inventory.md
- v2-separation-port-layer-audit.md
- v2-legacy-runtime-exit-criteria.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 02:13:08 -07:00

6.6 KiB

V2 Second Migration Task Pack

Date: 2026-04-04 Status: delivered

Purpose

This note turns the second separation batch into validate-able engineering tasks.

The first batch proved that contract ownership and translation authority already belong in sw-block. The second batch now targets the remaining physical coupling: backend bindings.

Shared Rules

All tasks in this pack inherit these rules:

  1. sw-block must not directly import weed/storage/blockvol
  2. reusable execution-muscle logic should move toward sw-block
  3. weed-side code should shrink toward thin concrete bindings
  4. no task in this pack may redefine engine semantics or recovery policy

Task E: Reader Backend-Binding Extraction

Goal

Extract reusable reader logic from direct BlockVol coupling so the BlockVol-specific part becomes a thin snapshot binding.

Source

  1. weed/storage/blockvol/v2bridge/reader.go
  2. weed/server/block_recovery.go reader shim

Destination

  1. reusable reader logic in sw-block/bridge/blockvol/runtime
  2. thin BlockVol snapshot binding in weed/storage/blockvol/v2bridge

Authority Rule

The reusable logic that shapes backend snapshot data into bridge.BlockVolState belongs with sw-block execution muscles.

The weed-side binder may fetch snapshot fields from real BlockVol, but it must not own the reusable state-shaping layer.

Adapter Boundary

weed/ may:

  1. call StatusSnapshot() on real BlockVol
  2. expose raw backend snapshot data to the extracted layer

weed/ must not:

  1. keep a second contract-shape mapping layer in block_recovery.go
  2. reinterpret retained-history meaning

Acceptance

  1. reusable reader logic no longer depends on direct BlockVol import
  2. weed/storage/blockvol/v2bridge/reader.go is reduced to thin binding code
  3. readerShimForRecovery is removed or reduced to trivial wiring

Validation

  1. go test ./sw-block/bridge/blockvol
  2. go test ./weed/storage/blockvol/v2bridge -run "TestReader_"
  3. if the recovery shim changes, run:
    • go test ./weed/server -run "TestP4_|TestP16B_"

Current proof anchors

  1. TestStorageAdapter_RetainedHistoryFromReader
  2. TestReader_RealBlockVol_StatusSnapshot
  3. TestReader_RealBlockVol_HeadAdvancesWithWrites

Task F: Pinner Backend-Binding Extraction

Goal

Extract hold bookkeeping and release lifecycle from direct BlockVol coupling so weed-side code only performs concrete retention-floor binding and state validation.

Source

  1. weed/storage/blockvol/v2bridge/pinner.go
  2. weed/server/block_recovery.go pinner shim

Destination

  1. reusable hold bookkeeping in sw-block/bridge/blockvol/runtime
  2. thin BlockVol retention binding in weed/storage/blockvol/v2bridge

Authority Rule

Hold bookkeeping is reusable execution-muscle logic. Concrete interaction with the flusher and StatusSnapshot() stays in weed/, but ID tracking and release symmetry should not require direct BlockVol imports.

Adapter Boundary

weed/ may:

  1. install retention-floor callbacks on real BlockVol
  2. validate requested hold positions against live backend snapshot state

weed/ must not:

  1. keep reusable hold lifecycle ownership trapped in weed/
  2. force recovery policy knowledge into the pinner binding

Acceptance

  1. reusable hold bookkeeping can live in sw-block without BlockVol imports
  2. weed-side pinner code shrinks toward concrete callback/state binding
  3. pinnerShimForRecovery is removed or reduced to trivial wiring

Validation

  1. go test ./sw-block/bridge/blockvol
  2. go test ./weed/storage/blockvol/v2bridge -run "TestPinner_|TestBridge_"
  3. if the recovery shim changes, run:
    • go test ./weed/server -run "TestP4_|TestP16B_"

Current proof anchors

  1. TestStorageAdapter_WALPinRejectsRecycled
  2. TestStorageAdapter_SnapshotPinRejectsUntrusted
  3. TestStorageAdapter_PinReleaseSymmetry
  4. TestPinner_RealBlockVol_HoldWALRetention
  5. TestPinner_RealBlockVol_HoldRejectsRecycled

Task G: Executor Backend-Capability Extraction

Goal

Split executor logic into:

  1. reusable orchestration that belongs with sw-block execution muscles
  2. concrete backend capabilities and wire operations that remain in weed/

Source

  1. weed/storage/blockvol/v2bridge/executor.go
  2. related tests in:
    • weed/storage/blockvol/v2bridge/*transfer*
    • weed/storage/blockvol/v2bridge/*snapshot*
    • weed/storage/blockvol/v2bridge/*truncate*

Destination

  1. reusable executor orchestration in sw-block/bridge/blockvol/runtime
  2. thin backend capability bindings in weed/storage/blockvol/v2bridge

Authority Rule

The engine still owns recovery policy. This task does not move policy.

The reusable execution sequence for:

  1. bounded WAL replay
  2. full-base install plus second catch-up
  3. snapshot transfer verification
  4. truncate escalation boundary

should no longer be inseparable from direct BlockVol imports.

Adapter Boundary

weed/ may:

  1. implement concrete backend operations on real BlockVol
  2. own rebuild TCP framing and network transport while it still depends on blockvol protocol types

weed/ must not:

  1. keep the whole recovery step orchestration trapped behind direct BlockVol imports when capability interfaces can be extracted
  2. redefine engine-visible boundary meaning

Acceptance

  1. executor reusable logic depends on extracted capability interfaces, not direct BlockVol imports
  2. weed-side executor code is reduced to concrete backend/network bindings
  3. outcome classification still remains outside the executor layer

Validation

  1. go test ./sw-block/bridge/blockvol
  2. go test ./weed/storage/blockvol/v2bridge -run "TestExecutor_|TestBridge_"
  3. focused runtime integration still passes:
    • go test ./weed/server -run "TestBlockService_ApplyAssignments_(PrimaryRole_UsesCoreStartRecoveryTaskForCatchUp|RebuildingRole_UsesCoreRecoveryPathWithoutLegacyDirectStart)"

Current proof anchors

  1. TestContract_BlockVolReaderInterface
  2. TestExecutor_RealBlockVol_StreamWALEntries
  3. TestExecutor_RealBlockVol_StreamPartialRange
  4. TestExecutor_ErrorPaths

Recommended order:

  1. Task E
  2. Task F
  3. Task G

Reason:

  1. reader extraction is lowest risk and pure read-path
  2. pinner extraction adds lifecycle but still avoids policy
  3. executor extraction is the largest surface and should build on the previous two cuts

Delivery Note

Final outcome:

  1. Task E was completed by code change
  2. Task F was completed by code change
  3. Task G was reviewed and confirmed already clean
  4. after Batch 2, weed/server/block_recovery.go no longer carries reader/pinner shim types