A high-performance Package Revision (PR) server for BitBake builds, rewritten in Rust with immediate SQLite persistence for reliability.
- Configurable sync modes - Choose between immediate, periodic, or on-shutdown persistence for optimal performance/safety balance
- Async TCP server - High-performance async networking with tokio
- BitBake compatibility - Drop-in replacement for the Python prserv
- History and no-history modes - Supports both PR increment modes
- Read-only mode - Safe querying without modifications
- Structured logging - Comprehensive logging with tracing
- Type-safe errors - Rust's error handling for reliability
This Rust implementation addresses key issues in the original Python prserv:
- Configurable persistence: Choose sync mode based on your needs - immediate for safety, periodic for balance, or on-shutdown for speed
- Better concurrency: Uses SQLite WAL mode for improved concurrent access
- Memory safety: Rust's ownership system prevents common memory issues
- Performance: Compiled binary with optimized SQLite operations and buffered writes
Build from source:
cargo build --release
The binary will be available at target/release/prserv
.
# Start server with default settings (localhost:8585, prserv.db)
prserv server
# Custom database and port
prserv server --database /path/to/prserv.db --bind 0.0.0.0:9090
# Read-only mode
prserv server --read-only
# No-history mode (no PR decrements)
prserv server --nohist
# Different sync modes
prserv server --sync-mode immediate # Default: safest, writes immediately
prserv server --sync-mode periodic:30 # Balanced: flush every 30 seconds
prserv server --sync-mode on_shutdown # Fastest: only sync on shutdown
# Get a PR value (creates if doesn't exist)
prserv client get-pr "1.0" "x86_64" "abc123hash"
# Test if PR exists
prserv client test-pr "1.0" "x86_64" "abc123hash"
# Check if package exists
prserv client test-package "1.0" "x86_64"
# Get maximum PR for package
prserv client max-package-pr "1.0" "x86_64"
# Import a PR value
prserv client import-one "1.0" "x86_64" "abc123hash" 42
# Export data
prserv client export --colinfo
# Check server status
prserv client ping
prserv client is-readonly
The server uses SQLite with the following table structure:
CREATE TABLE PRMAIN_hist (
version TEXT NOT NULL,
pkgarch TEXT NOT NULL,
checksum TEXT NOT NULL,
value INTEGER NOT NULL,
PRIMARY KEY (version, pkgarch, checksum)
);
CREATE TABLE PRMAIN_nohist (
version TEXT NOT NULL,
pkgarch TEXT NOT NULL,
checksum TEXT NOT NULL,
value INTEGER NOT NULL,
PRIMARY KEY (version, pkgarch, checksum)
);
The server supports JSON/YAML configuration files:
# config.yaml
server:
database: "/var/lib/prserv/prserv.db"
bind_addr: "0.0.0.0:8585"
read_only: false
nohist: false
sync_mode: immediate # or periodic: { interval_secs: 30 } or on_shutdown
client:
server_addr: "localhost:8585"
The server implements a JSON-RPC style protocol over TCP:
{
"id": "unique-request-id",
"method": "get-pr",
"params": {
"version": "1.0",
"pkgarch": "x86_64",
"checksum": "abc123hash"
}
}
{
"id": "unique-request-id",
"result": {"value": 42},
"error": null
}
get-pr
: Get/create PR valuetest-pr
: Test if PR existstest-package
: Test if package existsmax-package-pr
: Get maximum PR for packageimport-one
: Import PR valueexport
: Export PR datais-readonly
: Check server modeping
: Health check
- Configurable sync modes: Choose between immediate, periodic, or on-shutdown persistence
- WAL mode: Uses SQLite WAL journaling for better concurrency
- Buffered writes: Periodic and on-shutdown modes use intelligent write batching
- Better error handling: Type-safe error propagation
- Async architecture: Non-blocking I/O for better performance
- Safety: ⭐⭐⭐⭐⭐ Highest - Every write is immediately committed to disk
- Performance: ⭐⭐ Slowest - Each operation waits for disk I/O
- Use case: Production builds where data integrity is critical
- Safety: ⭐⭐⭐⭐ High - Writes are flushed every N seconds
- Performance: ⭐⭐⭐⭐ Balanced - Good throughput with regular safety checkpoints
- Use case: Development/CI environments with moderate safety requirements
- Configuration:
--sync-mode periodic:30
(flush every 30 seconds)
- Safety: ⭐⭐ Lowest - Data only written on graceful shutdown
- Performance: ⭐⭐⭐⭐⭐ Fastest - All writes are buffered in memory
- Use case: Testing or temporary builds where speed matters most
- Risk: Data loss if process crashes or is killed ungracefully
cargo build
cargo test
RUST_LOG=debug cargo run -- server
You can configure the server using environment variables:
# Server configuration
export PRSERV_DATABASE="/var/lib/prserv/prserv.db"
export PRSERV_BIND_ADDR="0.0.0.0:8585"
export PRSERV_READ_ONLY="false"
export PRSERV_NOHIST="false"
export PRSERV_SYNC_MODE="periodic:60" # or "immediate" or "on_shutdown"
# Client configuration
export PRSERV_SERVER_ADDR="localhost:8585"
# Start server with environment config
prserv server
Apache-2.0