• v0.6.6 48794c0dee

    v0.6.6 Stable

    x released this 2026-02-27 08:51:22 +00:00 | 1 commits to main since this release

    Signed by x
    GPG key ID: A14ACA8AB45A9C27

    VSKI v0.6.6

    Features

    Replica Identification and Routing

    Replicas can now identify themselves with a unique ID and public URL, enabling proper routing by load balancer and workflow executors.

    How It Works

    1. Replica Identification: Replicas send X-Replica-Id and X-Replica-Public-Url headers to master during sync
    2. Master Tracking: Master stores known replicas in _known_replicas table with their public URLs
    3. Response Headers: Replicas include X-Replica-Id header in all response
    4. Client SDK: Client automatically captures X-Replica-Id from responses and includes it in subsequent request
    5. Workflow Routing: Workers can specify replicaId when subscribing to workflows to route job to specific replicas

    Incremental Sync

    Replicas now use SQLite changesets for incremental synchronization instead of full database downloads, dramatically reducing sync time and bandwidth.

    How it Works

    1. Initial Sync: Fresh replicas download the full database from master
    2. Session Reset: After full download, replica resets master's session to ensure clean changeset tracking
    3. Schema Comparison: Replicas compute and compare schema hashes with master before attempting incremental sync
    4. Schema Migration: If schemas differ, replica fetches master schema and applies migrations (CREATE TABLE, ALTER TABLE, indexes, triggers, views)
    5. Changeset Application: After schema sync, replicas apply changesets for data changes (INSERT, UPDATE, DELETE)
    6. Automatic Fallback: If replica has no replication state, it downloads full database

    Schema Synchronization

    When schema changes are detected (new collections, field changes, indexes), replicas automatically migrate their schema:

    1. Hash-Based Detection: Schema hashes are computed from sqlite_master (tables, indexes, triggers, views)
    2. Schema Fetch: Replica fetches full schema from master via /api/replica/schema-sync
    3. Diff Computation: Replica computes schema diff (new tables, altered tables, new/dropped indexes, triggers, views)
    4. Migration Application: Replica applies schema migrations:
      • CREATE TABLE for new collections
      • ALTER TABLE ADD COLUMN for new fields (columns are never deleted or renamed)
      • CREATE INDEX, CREATE TRIGGER, CREATE VIEW for new objects
      • DROP INDEX, DROP TRIGGER, DROP VIEW for removed objects
      • Tables are never dropped on replica

    Configuration

    # Replica server configuration
    REPLICA_MODE=replica
    REPLICA_ID=my-replica-001        # Unique identifier for this replica
    PUBLIC_URL=https://replica.example.com  # Public URL for routing
    MASTER_URL=https://master.example.com
    SYNC_INTERVAL=60
    

    New Admin Endpoints

    Endpoint Description
    GET /api/admin/known-replicas List all known replicas that have synced with master
    GET /api/admin/known-replicas?with_public_url=true Filter replicas by presence of public URL

    Client SDK

    // Health check endpoint
    const isHealthy = await client.health();
    
    // Get list of known replicas from master
    const replicas = await client.replicas.listKnown();
    
    // Filter by those with public URLs
    const publicReplicas = await client.replicas.listKnown({ withPublicUrl: true });
    
    // Client automatically captures replicaId from responses
    const records = await client.collection('posts').getList(1, 10);
    console.log(client.replicaId); // Set from X-Replica-Id header
    
    // Route workflow to specific replica
    await client.workflow.start('my-workflow', { arg1: 'value' }, { replicaId: 'replica-001' });
    

    Web Dashboard

    • Connection modal displays known replicas with their IDs for allowing quick switching between master and replica servers
    • Health check endpoint used for connectivity verification

    Cron Job Handling on Replicas

    Cron jobs are now properly disabled on replicas to prevent duplicate execution and data conflicts.

    Behavior on Replicas

    • HTTP cron jobs: Always skipped on replicas (would cause duplicate external calls)
    • SQL cron jobs: Skipped for replicated databases (all databases except stats and workflows)
    • SQL cron jobs on non-replicated databases: Execute normally (e.g., cleanup jobs on stats or workflows)

    This ensures that:

    1. Replicas don't trigger duplicate HTTP webhooks
    2. SQL jobs don't conflict with master's data (replicated DBs are read-only)
    3. System maintenance jobs on non-replicated databases still run

    New Environment Variables

    Variable Default Description
    REPLICA_ID (none) Unique identifier for this replica instance
    PUBLIC_URL (none) Public URL for routing requests to this replica

    Technical Details

    New Replica API Endpoints

    Endpoint Method Description
    /api/replica/schema-sync GET Get full schema from master for migration (internal)
    /api/replica/reset-session POST Reset master's SQLite session after full download (internal)

    Files Changed

    • internal/replica/syncer.go - Incremental sync logic, schema comparison and migration, hash-based change detection
    • internal/replica/session_manager.go - Session management, ResetSession() method, schema hash computation, GetFullSchema()
    • internal/api/replica.go - ResetSession endpoint, SchemaSync endpoint, changeset generation
    • internal/config/config.go - Added ReplicaID and PublicURL config fields
    • internal/replica/middleware.go - Added X-Replica-Id to ReplicaStatusMiddleware
    • internal/replica/types.go - Added KnownReplica struct
    • internal/replica/registry.go - Added UpsertKnownReplica, ListKnownReplicas with filter
    • internal/db/db.go - Added _known_replicas table schema
    • internal/app/bootstrap.go - Pass cfg.ReplicaID to syncer and middleware, configure cron replica mode
    • internal/services/cron.go - Added replica mode support, skip jobs on replicated databases
    • client/src/client.ts - Added replicaId property, health() method, capture from response headers
    • client/src/types.ts - Added replicaId to WorkflowOptions
    • client/src/api/replicas.ts - New namespace for known replicas management
    • web/lib/sdk.tsx - Use /health endpoint for connectivity check
    • web/components/layout/ConnectionBadge.tsx - Display known replicas in server list

    Breaking Changes

    None

    Migration

    No migration required. The _known_replicas table is created automatically on startup.

    Downloads