batata-client 0.0.2

Rust client for Batata/Nacos service discovery and configuration management
Documentation
//! Naming service example
//!
//! This example demonstrates how to use the NamingService for:
//! - Registering service instances
//! - Querying service instances
//! - Subscribing to service changes

use batata_client::prelude::*;

#[tokio::main]
async fn main() -> Result<()> {
    // Initialize logging
    tracing_subscriber::fmt::init();

    // Create client
    let client = BatataClient::builder()
        .server_addr("localhost:8848")
        .namespace("public")
        .app_name("naming-example")
        .build()
        .await?;

    println!("Connected to Batata server!");

    let naming_service = client.naming_service();

    // Start naming service for heartbeat
    client.start_naming_service().await?;

    // Register a service instance
    println!("\n--- Registering service instance ---");
    let instance = Instance::new("127.0.0.1", 8080)
        .with_weight(1.0)
        .with_cluster("DEFAULT")
        .with_metadata("version", "1.0.0");

    naming_service
        .register_instance("example-service", "DEFAULT_GROUP", instance.clone())
        .await?;
    println!("Instance registered successfully!");

    // Register another instance
    let instance2 = Instance::new("127.0.0.1", 8081)
        .with_weight(2.0)
        .with_cluster("DEFAULT");

    naming_service
        .register_instance("example-service", "DEFAULT_GROUP", instance2)
        .await?;
    println!("Second instance registered successfully!");

    // Query all instances
    println!("\n--- Querying all instances ---");
    let instances = naming_service
        .get_all_instances("example-service", "DEFAULT_GROUP")
        .await?;
    println!("Found {} instances:", instances.len());
    for inst in &instances {
        println!("  - {}:{} (weight: {}, healthy: {})",
            inst.ip, inst.port, inst.weight, inst.healthy);
    }

    // Select healthy instances
    println!("\n--- Selecting healthy instances ---");
    let healthy = naming_service
        .select_instances("example-service", "DEFAULT_GROUP", true)
        .await?;
    println!("Found {} healthy instances", healthy.len());

    // Select one healthy instance
    println!("\n--- Selecting one healthy instance ---");
    match naming_service
        .select_one_healthy_instance("example-service", "DEFAULT_GROUP")
        .await
    {
        Ok(inst) => println!("Selected: {}:{}", inst.ip, inst.port),
        Err(e) => println!("No healthy instance: {}", e),
    }

    // Subscribe to service changes
    println!("\n--- Subscribing to service changes ---");
    naming_service
        .subscribe_callback("example-service", "DEFAULT_GROUP", |event| {
            println!("Service changed!");
            println!("  Service: {}", event.service_name);
            println!("  Instances count: {}", event.service.hosts.len());
        })
        .await?;
    println!("Subscribed successfully!");

    // Get services list
    println!("\n--- Getting services list ---");
    let (count, services) = naming_service
        .get_services_of_server("DEFAULT_GROUP", 1, 100)
        .await?;
    println!("Found {} services:", count);
    for service in services {
        println!("  - {}", service);
    }

    // Keep running for a while to demonstrate heartbeat
    println!("\n--- Keeping service alive for 10 seconds ---");
    tokio::time::sleep(tokio::time::Duration::from_secs(10)).await;

    // Deregister instances
    println!("\n--- Deregistering instances ---");
    naming_service
        .deregister_instance_simple("example-service", "127.0.0.1", 8080)
        .await?;
    naming_service
        .deregister_instance_simple("example-service", "127.0.0.1", 8081)
        .await?;
    println!("Instances deregistered!");

    // Shutdown
    client.shutdown().await;
    println!("\nClient shutdown complete.");

    Ok(())
}