Home

dev / openkara

publicthedavidweng/OpenKara· sync paused
Overview Code History Branches Pull requestsIssuesInsights
main
HomeOverview Code PRsIssues

feat(remote): versioned manifest, transactional publish, CAS conflict handling

2 months ago

d8371ec
Authored
Davy7/20/2026, 1:05:48 PM
Implement PR#4: versioned remote repository manifest, transactional
publish protocol, and CAS-based conflict handling.

New modules:
- errors.rs: typed RemoteError enum with RemoteErrorKind for
  machine-readable error codes persisted to remote_operations.
- manifest.rs: RepositoryManifest read/write/validate with
  generation-based database path layout (.openkara/databases/N.sqlite).
- executor.rs: 13-step transactional publish protocol with
  candidate DB copy, integrity check, upload, manifest CAS,
  re-verification, and GC scheduling. Includes conflict resolution
  functions (keep-local, use-remote, cancel) and disjoint-song
  auto-rebase for settings-compatible conflicts.

Provider trait extension (provider.rs):
- capabilities(): report conditional_replace, resumable_upload,
  range_download, revision_metadata, server_side_move.
- stat(): return RemoteObjectMetadata (size + revision).
- conditional_replace(): CAS-protected upload via ConditionalSource.

Provider implementations:
- Dropbox: rev-based CAS using mode:update with rev precondition.
  HTTP 409 maps to RemoteConflict.
- WebDAV: ETag-based CAS using If-Match for updates and
  If-None-Match:* for conditional-create. HTTP 412 maps to
  RemoteConflict.
- Google Drive: fail-closed (capabilities.conditional_replace=false)
  because the API v3 lacks If-Match/ETag conditional updates.

Control DB schema (002_manifest_columns.sql):
- Add repository_id and writer_id columns to remote_repository_state.
- Migration is idempotent: Rust runner checks column existence before
  ALTER TABLE ADD COLUMN (SQLite does not support IF NOT EXISTS for
  ADD COLUMN).

Publish refactor (publish.rs, mirror.rs):
- Replace legacy upload_remote_database with executor-driven
  commit_via_executor / commit_mirror_via_executor.
- Defect #2 fix: upload-complete event emitted ONLY after manifest
  CAS succeeds and is re-verified. Asset-upload failures never emit
  upload-complete.

Recovery (recovery.rs):
- Add retry_pending_operations to drive pending/retry_wait operations
  through the executor after startup recovery.

Tests: 8 executor tests covering first-generation publish, generation
advancement, CAS conflict detection, fail-closed for providers without
CAS, terminal operation idempotency, manifest verification, GC
scheduling, and repository/writer ID persistence.

Parent999b49c

17 files changed
  • src-tauri/migrations/remote_state/002_manifest_columns.sql+18−0
  • src-tauri/src/remote/atomic_download.rs+14−0
  • src-tauri/src/remote/bootstrap.rs+11−0
  • src-tauri/src/remote/control_db.rs+65−6
  • src-tauri/src/remote/dropbox.rs+129−0
  • src-tauri/src/remote/errors.rs+375−0
  • src-tauri/src/remote/executor.rs+1400−0
  • src-tauri/src/remote/google_drive.rs
+41
−0
  • src-tauri/src/remote/manifest.rs+404−0
  • src-tauri/src/remote/mod.rs+3−0
  • src-tauri/src/remote/mutation.rs+2−0
  • src-tauri/src/remote/provider.rs+81−1
  • src-tauri/src/remote/recovery.rs+113−3
  • src-tauri/src/remote/sync/mirror.rs+129−2
  • src-tauri/src/remote/sync/publish.rs+180−13
  • src-tauri/src/remote/sync/revision.rs+2−0
  • src-tauri/src/remote/webdav.rs+169−0