Skip to content

Latest commit

 

History

History
152 lines (114 loc) · 4.88 KB

File metadata and controls

152 lines (114 loc) · 4.88 KB

CAS Build Cache - Development Guidelines

This document provides context and guidelines for working with this codebase.

Project Overview

This is a gRPC-based LLVM Content-Addressable Storage (CAS) cache server compatible with Xcode 26's compilation cache system. It implements the LLVM remote caching protocol to cache build artifacts and speed up compilation.

Architecture

Core Components

  1. Proto definitions (proto/): gRPC service definitions from LLVM

    • compilation_caching_kv.proto - KeyValueDB service (action cache)
    • compilation_caching_cas.proto - CASDBService (content-addressable storage)
  2. Storage layer (src/storage/):

    • mod.rs - Trait definitions for CasStore and KvStore
    • memory.rs - In-memory implementation (for testing)
    • cas_file.rs - File-based CAS with SQLite metadata
    • cas_sqlite.rs - Full SQLite CAS storage
    • kv_sqlite.rs - SQLite KV storage
  3. Services (src/service/):

    • cas.rs - CASDBService gRPC implementation
    • kv.rs - KeyValueDB gRPC implementation
  4. Supporting modules:

    • hash.rs - BLAKE3 hashing with domain separation
    • eviction.rs - LRU/TTL cache eviction manager
    • export_cleanup.rs - Cleanup of exported files
    • config.rs - TOML configuration handling
    • error.rs - Error types
  5. Binaries (src/bin/):

    • server.rs - gRPC server daemon
    • cli.rs - CLI management tool

Key Design Decisions

Hashing

Uses BLAKE3 with domain separation:

  • Blobs: BLAKE3("cas-build-cache:blob:v1:" || data)
  • Objects: BLAKE3("cas-build-cache:object:v1:" || data || refs...)

Storage Strategy

  • File-based CAS (default): Best for large files, uses OS page cache
  • SQLite KV (default): Optimal for small action cache entries
  • Multi-level directory structure (configurable 1-3 levels) for file CAS

Eviction

  • LRU-based with high/low water marks (95%/85% default)
  • Evicts KV entries first, then CAS entries
  • Optional TTL-based eviction

Key Conflict Handling

Lenient mode by default (strict mode optional):

  • First value wins, subsequent mismatches are logged but not rejected
  • Prevents build failures from legitimately non-deterministic actions

Development Commands

# Build
cargo build
cargo build --release

# Test
cargo test                           # All tests
cargo test --test integration_tests  # Integration tests only
cargo test <test_name>               # Specific test

# Run server
cargo run --bin cas-cache-server
cargo run --bin cas-cache-server -- --socket /path/to/socket.sock

# Run CLI
cargo run --bin cas-cache-cli -- status
cargo run --bin cas-cache-cli -- list
cargo run --bin cas-cache-cli -- evict

Testing

Unit Tests

Located alongside the code they test (in #[cfg(test)] modules). Cover:

  • Hash generation and verification
  • Storage backends (file, SQLite, memory)
  • Service request/response handling
  • Eviction logic

Integration Tests

Located in tests/integration_tests.rs. Spin up real gRPC servers on Unix sockets and test end-to-end flows.

Configuration

Default locations checked:

  1. ~/.config/cas-build-cache/config.toml
  2. /etc/cas-build-cache/config.toml
  3. ./config.toml

Key settings:

  • server.socket_path - Unix socket path
  • storage.cas_backend - "file", "sqlite", or "memory"
  • storage.kv_backend - "sqlite" or "memory"
  • eviction.max_size - Cache size limit
  • eviction.policy - "lru", "ttl", or "lru_ttl"

Xcode Integration

Configure Xcode with these build settings:

COMPILATION_CACHE_ENABLE_CACHING=YES
COMPILATION_CACHE_ENABLE_PLUGIN=YES
COMPILATION_CACHE_REMOTE_SERVICE_PATH=$HOME/.local/state/cas-build-cache/cache.sock

Code Style

  • Use standard Rust formatting (cargo fmt)
  • Add #[cfg(test)] tests alongside modules
  • Use tracing for logging (debug, info, warn, error levels)
  • Error handling via thiserror custom error types
  • Async code uses tokio runtime

Performance Considerations

  • The cache handles thousands of requests per build
  • Keep per-RPC overhead minimal
  • Use read-optimized storage (file CAS leverages OS page cache)
  • Avoid global locks; storage uses per-entry locking
  • SQLite in WAL mode for concurrent access

Adding New Features

  1. New storage backend: Implement CasStore and/or KvStore traits
  2. New eviction policy: Add variant to EvictionPolicy enum in config.rs
  3. New CLI command: Add subcommand in cli.rs using clap

Proto Changes

If proto files need updates:

  1. Modify files in proto/
  2. Proto compilation happens automatically via build.rs
  3. Generated code is in target/ (not committed)

Troubleshooting

  • Socket permission denied: Check socket path permissions (mode 0600)
  • Cache not working: Ensure server is running, check socket path in Xcode settings
  • Slow builds: Check cache hit rate with cas-cache-cli status
  • Disk space issues: Review eviction settings, run cas-cache-cli evict