datafold 0.1.55

A personal database for data sovereignty with AI-powered ingestion
Documentation
/// Example demonstrating that HTTP client timeouts prevent indefinite hanging
///
/// Run with: cargo run --example test_timeout
use datafold::datafold_node::schema_client::SchemaServiceClient;
use datafold::schema::types::{JsonTopology, PrimitiveType, Schema, SchemaType, TopologyNode};
use std::collections::HashMap;
use std::time::Instant;

#[tokio::main]
async fn main() {
    println!("\n๐Ÿงช Testing Schema Service Client Timeout Fix");
    println!("==============================================\n");

    // Create a client pointing to a non-existent service (guaranteed to fail)
    let client = SchemaServiceClient::new("http://127.0.0.1:9999");

    // Create a simple test schema
    let mut schema = Schema::new(
        "TestSchema".to_string(),
        SchemaType::Single,
        None,
        Some(vec!["id".to_string(), "name".to_string()]),
        None,
        None,
    );

    // Add required field topologies
    schema.set_field_topology(
        "id".to_string(),
        JsonTopology::new(TopologyNode::Primitive {
            value: PrimitiveType::String,
            classifications: Some(vec!["word".to_string()]),
        }),
    );

    schema.set_field_topology(
        "name".to_string(),
        JsonTopology::new(TopologyNode::Primitive {
            value: PrimitiveType::String,
            classifications: Some(vec!["word".to_string()]),
        }),
    );

    schema.compute_schema_topology_hash();

    println!("๐Ÿ“ก Attempting to connect to: http://127.0.0.1:9999/api/schemas");
    println!("   (This service doesn't exist - testing timeout behavior)\n");
    println!("โฑ๏ธ  Expected: Timeout within 10-30 seconds");
    println!("โŒ Before fix: Would hang forever\n");

    let start = Instant::now();

    // Try to add schema - should timeout gracefully with our fix
    match client.add_schema(&schema, HashMap::new()).await {
        Ok(_) => {
            println!("โŒ ERROR: Unexpected success!");
            std::process::exit(1);
        }
        Err(e) => {
            let elapsed = start.elapsed();
            println!(
                "โœ… Request failed after {:.2} seconds",
                elapsed.as_secs_f64()
            );
            println!("๐Ÿ“ Error message:\n   {}\n", e);

            // Verify timeout happened within reasonable time
            if elapsed.as_secs() <= 35 {
                println!("โœ… SUCCESS: Timeout fix is working correctly!");
                println!(
                    "   โ€ข Request timed out in {} seconds (expected: 10-30s)",
                    elapsed.as_secs()
                );
                println!("   โ€ข Error message is clear and actionable");
                println!("   โ€ข No indefinite hanging occurred\n");
            } else {
                println!(
                    "โš ๏ธ  WARNING: Timeout took {} seconds (expected <35s)",
                    elapsed.as_secs()
                );
                println!(
                    "   This is longer than expected but still better than hanging forever.\n"
                );
            }
        }
    }

    println!("๐ŸŽฏ Test complete!");
}