Skip to content

avocado-linux/prserv

Repository files navigation

PR Server (prserv)

A high-performance Package Revision (PR) server for BitBake builds, rewritten in Rust and backed by PostgreSQL.

Integrating prserv into a cluster? See docs/integration.md for the design (PR-allocation correctness), requirements, the multi-tenant database-per-dataset model, and deployment guidance.

Features

  • PostgreSQL backend - Concurrency-safe storage; state lives in a shared database, not a local file
  • Concurrency-safe PR allocation - Atomic max+1 allocation with a uniqueness guard (see docs/integration.md)
  • 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

Architecture

This Rust implementation backs prserv with PostgreSQL so it can run as a stateless pod against a shared database:

  1. Concurrency-safe allocation: PR values are allocated with a single atomic SQL statement guarded by a UNIQUE(version, pkgarch, value) constraint with retry — multiple replicas against one database are safe (no single-writer requirement). See docs/integration.md.
  2. Durable per commit: every write is committed inline; there is no write buffer to lose on a crash.
  3. Memory safety: Rust's ownership system prevents common memory issues.

Installation

Build from source:

cargo build --release

The binary will be available at target/release/prserv.

Usage

Starting the Server

# Start server (defaults: localhost:8585, postgres://prserv@localhost:5432/prserv)
prserv server

# Custom database URL and bind address
prserv server --database postgres://user:pass@db-host:5432/prserv_2026 --bind 0.0.0.0:9090

# Cap the connection pool (size against the instance's max_connections budget)
prserv server --max-connections 64

# Read-only mode
prserv server --read-only

# No-history mode (no PR decrements)
prserv server --nohist

Client Commands

# 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

Database Schema

The server auto-creates its tables in the connected PostgreSQL database. The UNIQUE(version, pkgarch, value) constraint is what makes concurrent PR allocation safe — see docs/integration.md.

CREATE TABLE IF NOT EXISTS "PRMAIN_hist" (   -- history mode (default)
    version  TEXT   NOT NULL,
    pkgarch  TEXT   NOT NULL,
    checksum TEXT   NOT NULL,
    value    BIGINT NOT NULL,
    PRIMARY KEY (version, pkgarch, checksum),
    UNIQUE (version, pkgarch, value)
);
-- "PRMAIN_nohist" is identical; --nohist selects it.

Configuration

The server supports JSON/YAML configuration files:

# config.yaml
server:
  database: "postgres://user:pass@db-host:5432/prserv_2026"
  bind_addr: "0.0.0.0:8585"
  read_only: false
  nohist: false
client:
  server_addr: "localhost:8585"

Protocol

The server implements a JSON-RPC style protocol over TCP:

Request Format

{
    "id": "unique-request-id",
    "method": "get-pr",
    "params": {
        "version": "1.0",
        "pkgarch": "x86_64",
        "checksum": "abc123hash"
    }
}

Response Format

{
    "id": "unique-request-id",
    "result": {"value": 42},
    "error": null
}

Supported Methods

  • get-pr: Get/create PR value
  • test-pr: Test if PR exists
  • test-package: Test if package exists
  • max-package-pr: Get maximum PR for package
  • import-one: Import PR value
  • export: Export PR data
  • is-readonly: Check server mode
  • ping: Health check

Differences from Python Version

  1. PostgreSQL backend: state lives in a shared database, enabling a stateless service
  2. Concurrency-safe allocation: atomic max+1 with a uniqueness guard; safe across replicas
  3. Better error handling: type-safe error propagation
  4. Async architecture: non-blocking I/O for better performance

Note: the sqlite-era --sync-mode flag (immediate/periodic/on_shutdown) is deprecated and ignored — the postgres backend is durable per commit and has no write buffer. The flag is still accepted so old invocations don't break.

Development

Building

cargo build

Testing

cargo test

Running with logs

RUST_LOG=debug cargo run -- server

Environment Variables

You can configure the server using environment variables:

# Server configuration
export PRSERV_DATABASE="postgres://user:pass@db-host:5432/prserv_2026"
export PRSERV_BIND_ADDR="0.0.0.0:8585"
export PRSERV_MAX_CONNECTIONS="64"
export PRSERV_READ_ONLY="false"
export PRSERV_NOHIST="false"
# PRSERV_SYNC_MODE is accepted but ignored (sqlite-era; postgres is durable per commit)

# Client configuration
export PRSERV_SERVER_ADDR="localhost:8585"

# Start server with environment config
prserv server

License

Apache-2.0

About

Avocado Pacakage Revision Server

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors