use rhai_client::RhaiClientBuilder; use rhailib_worker::spawn_rhai_worker; use std::time::Duration; use tempfile::Builder; use tokio::sync::mpsc; const ALICE_ID: &str = "alice_pk"; const BOB_ID: &str = "bob_pk"; const CHARLIE_ID: &str = "charlie_pk"; const CIRCLE_ID: &str = "circle_pk"; const REDIS_URL: &str = "redis://127.0.0.1/"; #[tokio::main] async fn main() -> Result<(), Box> { env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init(); // Create a temporary directory for the database let temp_dir = Builder::new().prefix("rhai-example").tempdir()?; let db_path = temp_dir.path().to_str().unwrap().to_string(); // 1. Create a Rhai engine and register custom functionality let engine = rhailib_engine::create_heromodels_engine(); // 2. Spawn the Rhai worker let (shutdown_tx, shutdown_rx) = mpsc::channel(1); let worker_handle = tokio::spawn(spawn_rhai_worker( ALICE_ID.to_string(), db_path.clone(), engine, REDIS_URL.to_string(), shutdown_rx, false, // use_sentinel )); log::info!("Rhai worker spawned for circle: {}", ALICE_ID); // Give the worker a moment to start up tokio::time::sleep(Duration::from_secs(1)).await; // Alice populates her rhai worker let client_alice = RhaiClientBuilder::new() .redis_url(REDIS_URL) .caller_id(ALICE_ID) .build() .unwrap(); client_alice .new_play_request() .worker_id(&ALICE_ID) .context_id(&ALICE_ID) .script_path("examples/access_control/alice.rhai") .timeout(Duration::from_secs(10)) .await_response() .await .unwrap(); log::info!("Alice's database populated."); // Bob queries Alice's rhai worker let client_bob = RhaiClientBuilder::new() .redis_url(REDIS_URL) .caller_id(BOB_ID) .build() .unwrap(); client_bob .new_play_request() .worker_id(&ALICE_ID) .context_id(&ALICE_ID) .script_path("examples/access_control/bob.rhai") .timeout(Duration::from_secs(10)) .await_response() .await .unwrap(); log::info!("Bob's query to Alice's database completed."); // Charlie queries Alice's rhai worker let client_charlie = RhaiClientBuilder::new() .redis_url(REDIS_URL) .caller_id(CHARLIE_ID) .build() .unwrap(); client_charlie .new_play_request() .worker_id(&ALICE_ID) .context_id(&ALICE_ID) .script_path("examples/access_control/charlie.rhai") .timeout(Duration::from_secs(10)) .await_response() .await .unwrap(); log::info!("Charlie's query to Alice's database completed."); // Spawn the Rhai worker for Alice's and Charlie's circle let engine = rhailib_engine::create_heromodels_engine(); let (shutdown_tx, shutdown_rx) = mpsc::channel(1); let worker_handle = tokio::spawn(spawn_rhai_worker( CIRCLE_ID.to_string(), db_path.clone(), engine, REDIS_URL.to_string(), shutdown_rx, false, // use_sentinel )); // Alice populates the rhai worker of their circle with Charlie. let client_circle = RhaiClientBuilder::new() .redis_url(REDIS_URL) .caller_id(CIRCLE_ID) .build() .unwrap(); client_circle .new_play_request() .worker_id(&CIRCLE_ID) .context_id(&CIRCLE_ID) .script_path("examples/access_control/circle.rhai") .timeout(Duration::from_secs(10)) .await_response() .await .unwrap(); log::info!("Circles's database populated."); // Give the worker a moment to start up tokio::time::sleep(Duration::from_secs(1)).await; // Alice queries the rhai worker of their circle with Charlie. client_alice .new_play_request() .worker_id(&CIRCLE_ID) .context_id(&CIRCLE_ID) .script_path("examples/access_control/alice.rhai") .timeout(Duration::from_secs(10)) .await_response() .await .unwrap(); log::info!("Bob's query to Alice's database completed."); // Charlie queries Alice's rhai worker let client_charlie = RhaiClientBuilder::new() .redis_url(REDIS_URL) .caller_id(CHARLIE_ID) .build() .unwrap(); client_charlie .new_play_request() .worker_id(&ALICE_ID) .context_id(&ALICE_ID) .script_path("examples/access_control/charlie.rhai") .timeout(Duration::from_secs(10)) .await_response() .await .unwrap(); log::info!("Charlie's query to Alice's database completed."); // 5. Shutdown the worker (optional, could also let it run until program exits) log::info!("Signaling worker to shutdown..."); let _ = shutdown_tx.send(()).await; if let Err(e) = worker_handle.await { log::error!("Worker task panicked or encountered an error: {:?}", e); } log::info!("Worker shutdown complete."); Ok(()) }