//! Example of launching multiple circles and outputting their details to a file. //! //! This example demonstrates how to use the launcher library to start circles //! programmatically, similar to how the `launcher` binary works. //! //! # Usage //! //! ```sh //! cd src/launcher //! cargo run --example ourworld //! ``` //! //! This will: //! 1. Read the `circles.json` file in the `examples/ourworld` directory. //! 2. Launch all 7 circles defined in the config. //! 3. Create a `ourworld_output.json` file in the same directory with the details. //! 4. The launcher will run until you stop it with Ctrl+C. use circles_launcher::{run_launcher, Args}; use log::{error, info}; use serde::{Deserialize, Serialize}; use std::error::Error as StdError; use std::fs; use std::path::PathBuf; #[derive(Serialize, Deserialize, Debug)] struct OurWorldCircleConfig { pub public_key: String, pub init_script: Option, } #[tokio::main] async fn main() -> Result<(), Box> { println!("--- Launching OurWorld Example Programmatically ---"); let example_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("examples/ourworld"); let config_path = example_dir.join("circles.json"); let output_path = example_dir.join("ourworld_output.json"); println!("Using config file: {:?}", config_path); println!("Output will be written to: {:?}", output_path); if !config_path.exists() { let msg = format!("Configuration file not found at {:?}", config_path); error!("{}", msg); return Err(msg.into()); } let config_content = fs::read_to_string(&config_path)?; let ourworld_configs: Vec = match serde_json::from_str(&config_content) { Ok(configs) => configs, Err(e) => { error!( "Failed to parse {}: {}. Ensure it's a valid JSON array of circle configs.", config_path.display(), e ); return Err(e.into()); } }; if ourworld_configs.is_empty() { info!( "No circle configurations found in {}. Exiting.", config_path.display() ); return Ok(()); } // Convert OurWorld configs to circle strings for the new API let mut circle_strings = Vec::new(); for config in &ourworld_configs { let circle_str = if let Some(script) = &config.init_script { format!("{}:{}", config.public_key, script) } else { config.public_key.clone() }; circle_strings.push(circle_str); } // Manually construct the arguments for the new API let args = Args { port: 443, // Default port circles: circle_strings, redis_url: "redis://127.0.0.1:6379".to_string(), enable_auth: false, worker_binary: Some("../target/release/worker".to_string()), debug: true, // Enable debug logging for the example verbose: 2, // Set verbosity to max }; println!("Starting launcher with {} circles... Press Ctrl+C to exit.", ourworld_configs.len()); // The run_launcher function will setup logging, spawn circles, print the table, // and wait for a shutdown signal (Ctrl+C). run_launcher(args).await?; println!("--- OurWorld Example Finished ---"); Ok(()) }