add rhailib package

This commit is contained in:
timurgordon
2025-06-04 04:47:55 +03:00
parent 635af9ecee
commit 79b37cf9ce
31 changed files with 6075 additions and 0 deletions

26
examples/Cargo.toml Normal file
View File

@@ -0,0 +1,26 @@
[package]
name = "rhailib-examples"
version = "0.1.0"
edition = "2021"
publish = false # This is a package of examples, not meant to be published
[dependencies]
# Local Rhailib crates
# Allows 'use rhai_client::...'
rhai_client = { path = "../src/client" }
# Allows 'use worker_lib::...'
worker_lib = { path = "../src/worker", package = "worker" }
# External dependencies (versions aligned with other crates)
rhai = { version = "1.18.0", features = ["sync", "decimal"] }
tokio = { version = "1", features = ["macros", "rt-multi-thread", "time"] }
log = "0.4"
env_logger = "0.10"
[[bin]]
name = "example_math_worker"
path = "example_math_worker.rs"
[[bin]]
name = "example_string_worker"
path = "example_string_worker.rs"

10
examples/README.md Normal file
View File

@@ -0,0 +1,10 @@
# Rhailib Examples
This directory contains end-to-end examples demonstrating the usage of the `rhailib` project, showcasing how the `client`, `engine`, and `worker` crates interact.
## Available Examples
- **`example_math_worker.rs`**: This example demonstrates a worker that performs mathematical operations. It shows how to define Rhai scripts that call Rust functions exposed by the worker, process the results, and interact with the `rhailib` engine and client.
- **`example_string_worker.rs`**: This example showcases a worker focused on string manipulations. Similar to the math worker, it illustrates the setup for defining Rhai scripts, registering Rust functions for string operations, and the overall flow of execution within the `rhailib` ecosystem.
These examples serve as a practical guide to understanding the core functionalities and integration patterns within the `rhailib` project.

View File

@@ -0,0 +1,76 @@
use rhai::Engine;
use rhai_client::RhaiClient; // To submit tasks
use worker_lib::{run_worker_loop, Args as WorkerArgs}; // To run the worker
use std::time::Duration;
use tokio::time::sleep;
// Custom function for Rhai
fn add(a: i64, b: i64) -> i64 {
a + b
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
log::info!("Starting Math Worker Example...");
// 1. Configure and start the Rhai Worker with a custom engine
let mut math_engine = Engine::new();
math_engine.register_fn("add", add);
log::info!("Custom 'add' function registered with Rhai engine for Math Worker.");
let worker_args = WorkerArgs {
redis_url: "redis://127.0.0.1/".to_string(),
circles: vec!["math_circle".to_string()], // Worker listens on a specific queue
};
let worker_args_clone = worker_args.clone(); // Clone for the worker task
tokio::spawn(async move {
log::info!("Math Worker task starting...");
if let Err(e) = run_worker_loop(math_engine, worker_args_clone).await {
log::error!("Math Worker loop failed: {}", e);
}
});
// Give the worker a moment to start and connect
sleep(Duration::from_secs(1)).await;
// 2. Use RhaiClient to submit a script to the "math_circle"
let client = RhaiClient::new("redis://127.0.0.1/")?;
let script_content = r#"
let x = 10;
let y = add(x, 32); // Use the custom registered function
print("Math script: 10 + 32 = " + y);
y // Return the result
"#;
log::info!("Submitting math script to 'math_circle' and awaiting result...");
let timeout_duration = Duration::from_secs(10);
let poll_interval = Duration::from_millis(500);
match client.submit_script_and_await_result(
"math_circle",
script_content.to_string(),
None,
timeout_duration,
poll_interval
).await {
Ok(details) => {
log::info!("Math Worker Example: Task finished. Status: {}, Output: {:?}, Error: {:?}",
details.status, details.output, details.error);
if details.status == "completed" {
assert_eq!(details.output, Some("42".to_string()));
log::info!("Math Worker Example: Assertion for output 42 passed!");
Ok(())
} else {
log::error!("Math Worker Example: Task completed with error: {:?}", details.error);
Err(format!("Task failed with error: {:?}", details.error).into())
}
}
Err(e) => {
log::error!("Math Worker Example: Failed to get task result: {}", e);
Err(e.into())
}
}
}

View File

@@ -0,0 +1,76 @@
use rhai::Engine;
use rhai_client::RhaiClient; // To submit tasks
use worker_lib::{run_worker_loop, Args as WorkerArgs}; // To run the worker
use std::time::Duration;
use tokio::time::sleep;
// Custom function for Rhai
fn reverse_string(s: String) -> String {
s.chars().rev().collect()
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
log::info!("Starting String Worker Example...");
// 1. Configure and start the Rhai Worker with a custom engine
let mut string_engine = Engine::new();
string_engine.register_fn("reverse_it", reverse_string);
log::info!("Custom 'reverse_it' function registered with Rhai engine for String Worker.");
let worker_args = WorkerArgs {
redis_url: "redis://127.0.0.1/".to_string(),
circles: vec!["string_circle".to_string()], // Worker listens on a specific queue
};
let worker_args_clone = worker_args.clone();
tokio::spawn(async move {
log::info!("String Worker task starting...");
if let Err(e) = run_worker_loop(string_engine, worker_args_clone).await {
log::error!("String Worker loop failed: {}", e);
}
});
// Give the worker a moment to start and connect
sleep(Duration::from_secs(1)).await;
// 2. Use RhaiClient to submit a script to the "string_circle"
let client = RhaiClient::new("redis://127.0.0.1/")?;
let script_content = r#"
let original = "hello world";
let reversed = reverse_it(original);
print("String script: original = '" + original + "', reversed = '" + reversed + "'");
reversed // Return the result
"#;
log::info!("Submitting string script to 'string_circle' and awaiting result...");
let timeout_duration = Duration::from_secs(10);
let poll_interval = Duration::from_millis(500);
match client.submit_script_and_await_result(
"string_circle",
script_content.to_string(),
None,
timeout_duration,
poll_interval
).await {
Ok(details) => {
log::info!("String Worker Example: Task finished. Status: {}, Output: {:?}, Error: {:?}",
details.status, details.output, details.error);
if details.status == "completed" {
assert_eq!(details.output, Some("\"dlrow olleh\"".to_string())); // Rhai strings include quotes in `debug` format
log::info!("String Worker Example: Assertion for output \"dlrow olleh\" passed!");
Ok(())
} else {
log::error!("String Worker Example: Task completed with error: {:?}", details.error);
Err(format!("Task failed with error: {:?}", details.error).into())
}
}
Err(e) => {
log::error!("String Worker Example: Failed to get task result: {}", e);
Err(e.into())
}
}
}