Fleet Mode (slum)
When one tenement isn’t enough, use slum - the multi-server fleet orchestrator.
What is slum?
Section titled “What is slum?”slum (the neighborhood) coordinates tenement (the building) instances across a fleet of servers.
┌─────────────────────────────────────────┐│ slum (Fleet Database + Router) │├──────────────┬──────────────┬───────────┤│ tenement │ tenement │ tenement ││ (east-1) │ (west-1) │ (south-1) │└──────────────┴──────────────┴───────────┘1. Initialize the Fleet Database
Section titled “1. Initialize the Fleet Database”use slum::{SlumDb, Server};
#[tokio::main]async fn main() -> Result<()> { // Create/open the fleet database let db = SlumDb::init("slum.db").await?;
// Add buildings (tenement servers) to the fleet db.add_server(&Server { id: "east".into(), url: "http://east.example.com".into(), region: Some("us-east".into()), capacity_mb: 1024, ..Default::default() }).await?;
db.add_server(&Server { id: "west".into(), url: "http://west.example.com".into(), region: Some("us-west".into()), capacity_mb: 1024, ..Default::default() }).await?;
Ok(())}2. Route Tenants to Servers
Section titled “2. Route Tenants to Servers”use slum::{Tenant};
// Assign a tenant to a specific serverdb.add_tenant(&Tenant { domain: "customer-1.example.com".into(), server_id: "east".into(), process: "api".into(), instance_id: "prod".into(), ..Default::default()}).await?;
// Lookup where a tenant liveslet tenant = db.get_tenant_by_domain("customer-1.example.com").await?;println!("Tenant is on server: {}", tenant.server_id);3. Orchestrate Spawn/Stop Across Fleet
Section titled “3. Orchestrate Spawn/Stop Across Fleet”// Spawn instance across fleetdb.spawn_instance( "customer-2", "api", "prod", "west" // target server).await?;
// Stop instance (slum finds the right server)db.stop_instance("customer-2:prod").await?;
// List all instances across all serverslet instances = db.list_all_instances().await?;Server Management
Section titled “Server Management”// Add serverdb.add_server(&Server { id: "east".into(), url: "http://east.example.com".into(), capacity_mb: 2048, ..Default::default()}).await?;
// Update serverdb.update_server(&updated_server).await?;
// List serverslet servers = db.list_servers().await?;
// Get server statslet stats = db.get_server_stats("east").await?;Tenant Management
Section titled “Tenant Management”// Add tenantdb.add_tenant(&Tenant { domain: "customer.example.com".into(), server_id: "east".into(), process: "api".into(), instance_id: "prod".into(), ..Default::default()}).await?;
// Get tenantlet tenant = db.get_tenant_by_domain("customer.example.com").await?;
// List tenants on serverlet tenants = db.list_tenants_on_server("east").await?;
// Reassign tenant to different serverdb.update_tenant(&updated_tenant).await?;Instance Management
Section titled “Instance Management”// Spawn on specific serverdb.spawn_instance( "customer-3", "api", "prod", "east").await?;
// Stop (slum finds server automatically)db.stop_instance("customer-3:prod").await?;
// List instances on serverlet instances = db.list_instances_on_server("east").await?;
// Get instance statuslet status = db.get_instance_status("customer-3:prod").await?;Use Cases
Section titled “Use Cases”Geographic Distribution
Section titled “Geographic Distribution”Route tenants to nearest server:
let tenant = db.get_tenant_by_domain("customer.example.com").await?;if let Some(region) = customer.preferred_region { // Find server in that region let server = db.find_server_in_region(®ion).await?; // Reassign tenant tenant.server_id = server.id; db.update_tenant(&tenant).await?;}Load Balancing
Section titled “Load Balancing”Distribute new tenants based on server capacity:
let servers = db.list_servers().await?;let least_used = servers .iter() .min_by_key(|s| s.used_capacity_mb()) .expect("No servers available");
db.spawn_instance( &new_customer_id, "api", "prod", &least_used.id).await?;High Availability
Section titled “High Availability”Mirror tenants across servers:
// Primary instancedb.spawn_instance("customer-4", "api", "prod", "east").await?;
// Backup instancedb.spawn_instance("customer-4", "api", "backup", "west").await?;
// Route to primary, fail over to backup if neededData Model
Section titled “Data Model”Server
Section titled “Server”| Field | Type | Description |
|---|---|---|
id | String | Unique server ID (e.g., “east-1”) |
url | String | Server URL (e.g., “http://east-1.example.com”) |
region | Option | Region (e.g., “us-east”) |
capacity_mb | i64 | Total available memory (MB) |
created_at | DateTime | Creation timestamp |
Tenant
Section titled “Tenant”| Field | Type | Description |
|---|---|---|
domain | String | Customer domain (e.g., “acme.example.com”) |
server_id | String | Home server ID |
process | String | Process name (e.g., “api”) |
instance_id | String | Instance ID (e.g., “prod”) |
created_at | DateTime | Creation timestamp |
Foreign Key Enforcement
Section titled “Foreign Key Enforcement”slum enforces referential integrity:
- Tenant’s
server_idmust exist - Can’t delete server with active tenants
- Can’t update non-existent tenant
Next Steps
Section titled “Next Steps”- Quick Start - Single-server setup
- Configuration Reference - tenement config reference