Files
Jamie Pineandcapy-ai-staging[bot] 10dbc18d0f Replica fetch: resumable .part transfers, bandwidth cap, pause, and progress (#3109)
* Resume interrupted replica fetches from a .part file

A replica transfer now lands in <source>.<generation>.<blake3 prefix>.part
and stays there when the stream breaks or the daemon stops. The next
attempt asks the owner for the artifact's tail from the part's length over
the new FetchSnapshotFrom and FetchDatabaseFrom requests, whose header
still names the whole artifact; a header that names different bytes
discards the part and starts over, and the finished file is validated
against the header checksum before it replaces the live replica as before.
Parts are removed only when the owner's listing no longer carries their
generation. A nonzero offset serves the on-disk snapshot without the
pre-fetch save, so a resumed copy finishes against the same bytes.

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>

* Cap replica transfer bandwidth with a persisted daemon setting

replication.max_bytes_per_sec in spacedrive.json bounds every replica
artifact served and received through one token bucket (zero is
unlimited); the cap applies to transfers already in flight. It is set
through config.app.update and sd config set replication.max_bytes_per_sec
(bytes, or K/M/G suffixes), read back through sd config get and show.

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>

* Pause and resume replica fetching

sd sources replication pause stops this device starting replica
transfers and halts any in flight at its next chunk, keeping the partial
file; resume continues from it and runs a replication pass against every
connected device at once. The switch is replication.paused in the daemon
config, so a paused daemon stays paused across a restart, and a pass that
runs while paused still refreshes listings, owner facts and fleet totals.
A pause does not count as a fetch failure, so no backoff accrues.

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>

* Show replica fetch progress in sources list, status and events

Every fetch in flight is tracked with bytes on disk, total and a recent
rate. sources.list carries it on the replica's row (or a replica_fetching
row for a first copy that has no share yet), core.status and the new
mounts.replication_status query summarize it with the pause switch and
cap, and the daemon emits a typed ReplicationProgress event about once a
second per transfer plus a finished one when it stops. sd sources list and
sd status print the figures; ts-client types regenerated.

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>

* Document resumable replica fetch, the cap, pause and progress

Source replication gets its own section in networking.mdx with the .part
contract, the wire change, the cap, the pause switch and the progress
fields; file-sync.mdx points there; the replication plan marks its cleanup
item superseded on the replica side and distinct from the restart refetch;
PROJECT_STATUS.md gains the register row.

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>

* Keep the part when a resumed request gets no header; cap sidecar pages

A resumed request that fails outright (dropped link, or an owner too old
to know the offset variants) says nothing about the bytes on disk, so the
part now stays and the whole-file retry lands on the same name. Sidecar
pages count against the bandwidth cap on both ends, as the setting's
contract says.

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>

* Add the replication field to the test harness config

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>

* Check the pause switch after the cap's wait, not before

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>

---------

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>
2026-10-05 11:40:19 +00:00
..
2026-08-21 13:47:42 -07:00
…
…
…

Spacedrive Core

Rust library implementing the Virtual Distributed File System (VDFS) architecture for local-first, AI-native file management.

Architecture

Structure

src/
├── domain/        # Core data models (Entry, Library, Device)
├── ops/           # Operations (actions and queries, CQRS pattern)
├── infra/         # Infrastructure (database, events, wire protocol)
├── service/       # High-level services (network, jobs, sessions)
├── location/      # Location management and indexing
├── library/       # Library lifecycle and operations
├── device/        # Device identity and management
├── volume/        # Volume detection and fingerprinting
├── config/        # Application configuration
├── crypto/        # Cryptographic primitives
└── bin/           # Binaries (cli, daemon)

Core Components

Core Manager (Core struct in lib.rs)

  • Coordinates all subsystems
  • Manages application lifecycle
  • Provides unified access to capabilities

Library (library/)

  • File-based storage (.sdlibrary directories)
  • SQLite database with SeaORM
  • Job management and thumbnail generation
  • Device registration and sync coordination

Entry-Centric Model (domain/entry.rs)

  • Unified representation for files and directories
  • Conditional UUIDs (directories immediate, files after content ID)
  • On-demand UserMetadata creation
  • Relative paths from location roots

Device Management (device/)

  • Single device identity per installation
  • Persistent across restarts (device.json)
  • Sync leadership model per library
  • Network address tracking for P2P

Operations Layer (ops/)

  • CQRS pattern: Actions (mutations) and Queries (reads)
  • Wire protocol with automatic type generation
  • Registry system using inventory crate
  • Shared across daemon RPC, iOS FFI, and WASM extensions

Infrastructure (infra/)

  • api/: Wire protocol dispatcher and RPC server
  • event/: Event bus for state changes
  • action/: Transactional action system with preview-commit-verify
  • query/: Read-optimized query handlers

Networking (service/network/)

  • Iroh-based P2P networking
  • Device pairing protocol
  • File transfer (Spacedrop)
  • mDNS local discovery

Jobs (service/jobs/)

  • Durable, resumable operations
  • MessagePack serialization for state
  • Progress reporting and cancellation
  • Per-library job managers

Indexing (location/indexer/)

  • Five-phase pipeline (discover, classify, extract, thumbnail, cleanup)
  • File system watcher integration
  • Rules engine with glob patterns
  • Resumable with checkpoints

Volume Management (volume/)

  • Cross-platform volume detection
  • Fingerprinting for identity
  • Mount point tracking

Communication Patterns

Daemon-Client (Desktop/CLI)

  • Unix socket JSON-RPC 2.0
  • Wire method strings (e.g., query:vdfs.list_entries)
  • Operations auto-register at compile time

Embedded FFI (iOS/Mobile)

  • Direct Rust library integration
  • Same JSON-RPC protocol over FFI
  • Swift client with Specta-generated types

Extensions (WASM)

  • Sandboxed WASM modules
  • Minimal host functions (log, register_job)
  • SDK with procedural macros (crates/sdk/)
  • Models, jobs, actions, agents, UI manifests

Key Technologies

  • Async runtime: tokio
  • Database: SQLite via SeaORM
  • Serialization: serde, Specta for type generation
  • Networking: Iroh (P2P), mdns-sd (local discovery)
  • WASM: wasmer runtime, spacedrive-sdk
  • Jobs: inventory for registration, rmp-serde for state
  • Crypto: blake3 (content addressing), ed25519 (signing)
  • Indexing: notify (fs watcher), globset (rules)

Building

# Full build
cargo build --release

# With optional features
cargo build --features ffmpeg,ai,heif

# Specific binary
cargo build --bin spacedrive
cargo build --bin daemon

# Run CLI
cargo run --bin spacedrive -- --help

Binaries

  • spacedrive: CLI interface
  • daemon: Background daemon process

Development

  • Uses CQRS and DDD patterns
  • Operations register via inventory crate macros
  • Resumable jobs with MessagePack state serialization
  • Type-safe Wire protocol with Specta generation
  • Event-driven architecture with EventBus
  • No layered architecture (direct Rust patterns)

Testing

# All tests
cargo test

# Specific module
cargo test --lib location::indexer

# Integration tests
cargo test --test indexer_test

See /docs/core/ for detailed architecture documentation.