rename worker to actor
This commit is contained in:
113
_archive/core/actor/cmd/README.md
Normal file
113
_archive/core/actor/cmd/README.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# Rhai Actor Binary
|
||||
|
||||
A command-line actor for executing Rhai scripts from Redis task queues.
|
||||
|
||||
## Binary: `actor`
|
||||
|
||||
### Installation
|
||||
|
||||
Build the binary:
|
||||
```bash
|
||||
cargo build --bin actor --release
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
# Basic usage - requires circle public key
|
||||
actor --circle-public-key <CIRCLE_PUBLIC_KEY>
|
||||
|
||||
# Custom Redis URL
|
||||
actor -c <CIRCLE_PUBLIC_KEY> --redis-url redis://localhost:6379/1
|
||||
|
||||
# Custom actor ID and database path
|
||||
actor -c <CIRCLE_PUBLIC_KEY> --actor-id my_actor --db-path /tmp/actor_db
|
||||
|
||||
# Preserve tasks for debugging/benchmarking
|
||||
actor -c <CIRCLE_PUBLIC_KEY> --preserve-tasks
|
||||
|
||||
# Remove timestamps from logs
|
||||
actor -c <CIRCLE_PUBLIC_KEY> --no-timestamp
|
||||
|
||||
# Increase verbosity
|
||||
actor -c <CIRCLE_PUBLIC_KEY> -v # Debug logging
|
||||
actor -c <CIRCLE_PUBLIC_KEY> -vv # Full debug
|
||||
actor -c <CIRCLE_PUBLIC_KEY> -vvv # Trace logging
|
||||
```
|
||||
|
||||
### Command-Line Options
|
||||
|
||||
| Option | Short | Default | Description |
|
||||
|--------|-------|---------|-------------|
|
||||
| `--circle-public-key` | `-c` | **Required** | Circle public key to listen for tasks |
|
||||
| `--redis-url` | `-r` | `redis://localhost:6379` | Redis connection URL |
|
||||
| `--actor-id` | `-w` | `actor_1` | Unique actor identifier |
|
||||
| `--preserve-tasks` | | `false` | Preserve task details after completion |
|
||||
| `--db-path` | | `actor_rhai_temp_db` | Database path for Rhai engine |
|
||||
| `--no-timestamp` | | `false` | Remove timestamps from log output |
|
||||
| `--verbose` | `-v` | | Increase verbosity (stackable) |
|
||||
|
||||
### Features
|
||||
|
||||
- **Task Queue Processing**: Listens to Redis queues for Rhai script execution tasks
|
||||
- **Performance Optimized**: Configured for maximum Rhai engine performance
|
||||
- **Graceful Shutdown**: Supports shutdown signals for clean termination
|
||||
- **Flexible Logging**: Configurable verbosity and timestamp control
|
||||
- **Database Integration**: Uses heromodels for data persistence
|
||||
- **Task Cleanup**: Optional task preservation for debugging/benchmarking
|
||||
|
||||
### How It Works
|
||||
|
||||
1. **Queue Listening**: Actor listens on Redis queue `baobab:{circle_public_key}`
|
||||
2. **Task Processing**: Receives task IDs, fetches task details from Redis
|
||||
3. **Script Execution**: Executes Rhai scripts with configured engine
|
||||
4. **Result Handling**: Updates task status and sends results to reply queues
|
||||
5. **Cleanup**: Optionally cleans up task details after completion
|
||||
|
||||
### Configuration Examples
|
||||
|
||||
#### Development Actor
|
||||
```bash
|
||||
# Simple development actor
|
||||
actor -c dev_circle_123
|
||||
|
||||
# Development with verbose logging (no timestamps)
|
||||
actor -c dev_circle_123 -v --no-timestamp
|
||||
```
|
||||
|
||||
#### Production Actor
|
||||
```bash
|
||||
# Production actor with custom configuration
|
||||
actor \
|
||||
--circle-public-key prod_circle_456 \
|
||||
--redis-url redis://redis-server:6379/0 \
|
||||
--actor-id prod_actor_1 \
|
||||
--db-path /var/lib/actor/db \
|
||||
--preserve-tasks
|
||||
```
|
||||
|
||||
#### Benchmarking Actor
|
||||
```bash
|
||||
# Actor optimized for benchmarking
|
||||
actor \
|
||||
--circle-public-key bench_circle_789 \
|
||||
--preserve-tasks \
|
||||
--no-timestamp \
|
||||
-vv
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
|
||||
The actor provides clear error messages for:
|
||||
- Missing or invalid circle public key
|
||||
- Redis connection failures
|
||||
- Script execution errors
|
||||
- Database access issues
|
||||
|
||||
### Dependencies
|
||||
|
||||
- `baobab_engine`: Rhai engine with heromodels integration
|
||||
- `redis`: Redis client for task queue management
|
||||
- `rhai`: Script execution engine
|
||||
- `clap`: Command-line argument parsing
|
||||
- `env_logger`: Logging infrastructure
|
233
_archive/core/actor/cmd/osis.rs
Normal file
233
_archive/core/actor/cmd/osis.rs
Normal file
@@ -0,0 +1,233 @@
|
||||
//! OSIS Actor Binary - Synchronous actor for system-level operations
|
||||
|
||||
use clap::Parser;
|
||||
use log::{error, info};
|
||||
use baobab_actor::config::{ConfigError, ActorConfig};
|
||||
use baobab_actor::engine::create_heromodels_engine;
|
||||
use baobab_actor::sync_actor::SyncActor;
|
||||
use baobab_actor::actor_trait::{spawn_actor, ActorConfig as TraitActorConfig};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use tokio::signal;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(
|
||||
name = "osis",
|
||||
version = "0.1.0",
|
||||
about = "OSIS (Operating System Integration Service) - Synchronous Actor",
|
||||
long_about = "A synchronous actor for Hero framework that processes jobs sequentially. \
|
||||
Ideal for system-level operations that require careful resource management."
|
||||
)]
|
||||
struct Args {
|
||||
/// Path to TOML configuration file
|
||||
#[arg(short, long, help = "Path to TOML configuration file")]
|
||||
config: PathBuf,
|
||||
|
||||
/// Override actor ID from config
|
||||
#[arg(long, help = "Override actor ID from configuration file")]
|
||||
actor_id: Option<String>,
|
||||
|
||||
/// Override Redis URL from config
|
||||
#[arg(long, help = "Override Redis URL from configuration file")]
|
||||
redis_url: Option<String>,
|
||||
|
||||
/// Override database path from config
|
||||
#[arg(long, help = "Override database path from configuration file")]
|
||||
db_path: Option<String>,
|
||||
|
||||
/// Enable verbose logging (debug level)
|
||||
#[arg(short, long, help = "Enable verbose logging")]
|
||||
verbose: bool,
|
||||
|
||||
/// Disable timestamps in log output
|
||||
#[arg(long, help = "Remove timestamps from log output")]
|
||||
no_timestamp: bool,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let args = Args::parse();
|
||||
|
||||
// Load configuration from TOML file
|
||||
let mut config = match ActorConfig::from_file(&args.config) {
|
||||
Ok(config) => config,
|
||||
Err(e) => {
|
||||
eprintln!("Failed to load configuration from {:?}: {}", args.config, e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
// Validate that this is a sync actor configuration
|
||||
if !config.is_sync() {
|
||||
eprintln!("Error: OSIS actor requires a sync actor configuration");
|
||||
eprintln!("Expected: [actor_type] type = \"sync\"");
|
||||
eprintln!("Found: {:?}", config.actor_type);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
// Apply command line overrides
|
||||
if let Some(actor_id) = args.actor_id {
|
||||
config.actor_id = actor_id;
|
||||
}
|
||||
if let Some(redis_url) = args.redis_url {
|
||||
config.redis_url = redis_url;
|
||||
}
|
||||
if let Some(db_path) = args.db_path {
|
||||
config.db_path = db_path;
|
||||
}
|
||||
|
||||
// Configure logging
|
||||
setup_logging(&config, args.verbose, args.no_timestamp)?;
|
||||
|
||||
info!("🚀 OSIS Actor starting...");
|
||||
info!("Actor ID: {}", config.actor_id);
|
||||
info!("Redis URL: {}", config.redis_url);
|
||||
info!("Database Path: {}", config.db_path);
|
||||
info!("Preserve Tasks: {}", config.preserve_tasks);
|
||||
|
||||
// Create Rhai engine
|
||||
let engine = create_heromodels_engine();
|
||||
info!("✅ Rhai engine initialized");
|
||||
|
||||
// Create actor configuration for the trait-based interface
|
||||
let actor_config = TraitActorConfig::new(
|
||||
config.actor_id.clone(),
|
||||
config.db_path.clone(),
|
||||
config.redis_url.clone(),
|
||||
config.preserve_tasks,
|
||||
);
|
||||
|
||||
// Create sync actor instance
|
||||
let actor = Arc::new(SyncActor::default());
|
||||
info!("✅ Sync actor instance created");
|
||||
|
||||
// Setup shutdown signal handling
|
||||
let (shutdown_tx, shutdown_rx) = mpsc::channel(1);
|
||||
|
||||
// Spawn shutdown signal handler
|
||||
let shutdown_tx_clone = shutdown_tx.clone();
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = signal::ctrl_c().await {
|
||||
error!("Failed to listen for shutdown signal: {}", e);
|
||||
return;
|
||||
}
|
||||
info!("🛑 Shutdown signal received");
|
||||
if let Err(e) = shutdown_tx_clone.send(()).await {
|
||||
error!("Failed to send shutdown signal: {}", e);
|
||||
}
|
||||
});
|
||||
|
||||
// Spawn the actor
|
||||
info!("🔄 Starting actor loop...");
|
||||
let actor_handle = spawn_actor(actor, engine, shutdown_rx);
|
||||
|
||||
// Wait for the actor to complete
|
||||
match actor_handle.await {
|
||||
Ok(Ok(())) => {
|
||||
info!("✅ OSIS Actor shut down gracefully");
|
||||
}
|
||||
Ok(Err(e)) => {
|
||||
error!("❌ OSIS Actor encountered an error: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
Err(e) => {
|
||||
error!("❌ Failed to join actor task: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Setup logging based on configuration and command line arguments
|
||||
fn setup_logging(
|
||||
config: &ActorConfig,
|
||||
verbose: bool,
|
||||
no_timestamp: bool,
|
||||
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let mut builder = env_logger::Builder::new();
|
||||
|
||||
// Determine log level
|
||||
let log_level = if verbose {
|
||||
"debug"
|
||||
} else {
|
||||
&config.logging.level
|
||||
};
|
||||
|
||||
// Set log level
|
||||
builder.filter_level(match log_level.to_lowercase().as_str() {
|
||||
"trace" => log::LevelFilter::Trace,
|
||||
"debug" => log::LevelFilter::Debug,
|
||||
"info" => log::LevelFilter::Info,
|
||||
"warn" => log::LevelFilter::Warn,
|
||||
"error" => log::LevelFilter::Error,
|
||||
_ => {
|
||||
eprintln!("Invalid log level: {}. Using 'info'", log_level);
|
||||
log::LevelFilter::Info
|
||||
}
|
||||
});
|
||||
|
||||
// Configure timestamps
|
||||
let show_timestamps = !no_timestamp && config.logging.timestamps;
|
||||
if !show_timestamps {
|
||||
builder.format_timestamp(None);
|
||||
}
|
||||
|
||||
builder.init();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::io::Write;
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
#[test]
|
||||
fn test_config_validation() {
|
||||
let config_toml = r#"
|
||||
actor_id = "test_osis"
|
||||
redis_url = "redis://localhost:6379"
|
||||
db_path = "/tmp/test_db"
|
||||
|
||||
[actor_type]
|
||||
type = "sync"
|
||||
|
||||
[logging]
|
||||
level = "info"
|
||||
"#;
|
||||
|
||||
let mut temp_file = NamedTempFile::new().unwrap();
|
||||
temp_file.write_all(config_toml.as_bytes()).unwrap();
|
||||
|
||||
let config = ActorConfig::from_file(temp_file.path()).unwrap();
|
||||
assert!(config.is_sync());
|
||||
assert!(!config.is_async());
|
||||
assert_eq!(config.actor_id, "test_osis");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_async_config_rejection() {
|
||||
let config_toml = r#"
|
||||
actor_id = "test_osis"
|
||||
redis_url = "redis://localhost:6379"
|
||||
db_path = "/tmp/test_db"
|
||||
|
||||
[actor_type]
|
||||
type = "async"
|
||||
default_timeout_seconds = 300
|
||||
|
||||
[logging]
|
||||
level = "info"
|
||||
"#;
|
||||
|
||||
let mut temp_file = NamedTempFile::new().unwrap();
|
||||
temp_file.write_all(config_toml.as_bytes()).unwrap();
|
||||
|
||||
let config = ActorConfig::from_file(temp_file.path()).unwrap();
|
||||
assert!(!config.is_sync());
|
||||
assert!(config.is_async());
|
||||
// This would be rejected in main() function
|
||||
}
|
||||
}
|
302
_archive/core/actor/cmd/system.rs
Normal file
302
_archive/core/actor/cmd/system.rs
Normal file
@@ -0,0 +1,302 @@
|
||||
//! System Actor Binary - Asynchronous actor for high-throughput concurrent processing
|
||||
|
||||
use clap::Parser;
|
||||
use log::{error, info, warn};
|
||||
use baobab_actor::async_actor_impl::AsyncActor;
|
||||
use baobab_actor::config::{ConfigError, ActorConfig};
|
||||
use baobab_actor::engine::create_heromodels_engine;
|
||||
use baobab_actor::actor_trait::{spawn_actor, ActorConfig as TraitActorConfig};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tokio::signal;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(
|
||||
name = "system",
|
||||
version = "0.1.0",
|
||||
about = "System Actor - Asynchronous Actor with Concurrent Job Processing",
|
||||
long_about = "An asynchronous actor for Hero framework that processes multiple jobs \
|
||||
concurrently with timeout support. Ideal for high-throughput scenarios \
|
||||
where jobs can be executed in parallel."
|
||||
)]
|
||||
struct Args {
|
||||
/// Path to TOML configuration file
|
||||
#[arg(short, long, help = "Path to TOML configuration file")]
|
||||
config: PathBuf,
|
||||
|
||||
/// Override actor ID from config
|
||||
#[arg(long, help = "Override actor ID from configuration file")]
|
||||
actor_id: Option<String>,
|
||||
|
||||
/// Override Redis URL from config
|
||||
#[arg(long, help = "Override Redis URL from configuration file")]
|
||||
redis_url: Option<String>,
|
||||
|
||||
/// Override database path from config
|
||||
#[arg(long, help = "Override database path from configuration file")]
|
||||
db_path: Option<String>,
|
||||
|
||||
/// Override default timeout in seconds
|
||||
#[arg(long, help = "Override default job timeout in seconds")]
|
||||
timeout: Option<u64>,
|
||||
|
||||
/// Enable verbose logging (debug level)
|
||||
#[arg(short, long, help = "Enable verbose logging")]
|
||||
verbose: bool,
|
||||
|
||||
/// Disable timestamps in log output
|
||||
#[arg(long, help = "Remove timestamps from log output")]
|
||||
no_timestamp: bool,
|
||||
|
||||
/// Show actor statistics periodically
|
||||
#[arg(long, help = "Show periodic actor statistics")]
|
||||
show_stats: bool,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let args = Args::parse();
|
||||
|
||||
// Load configuration from TOML file
|
||||
let mut config = match ActorConfig::from_file(&args.config) {
|
||||
Ok(config) => config,
|
||||
Err(e) => {
|
||||
eprintln!("Failed to load configuration from {:?}: {}", args.config, e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
// Validate that this is an async actor configuration
|
||||
if !config.is_async() {
|
||||
eprintln!("Error: System actor requires an async actor configuration");
|
||||
eprintln!("Expected: [actor_type] type = \"async\"");
|
||||
eprintln!("Found: {:?}", config.actor_type);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
// Apply command line overrides
|
||||
if let Some(actor_id) = args.actor_id {
|
||||
config.actor_id = actor_id;
|
||||
}
|
||||
if let Some(redis_url) = args.redis_url {
|
||||
config.redis_url = redis_url;
|
||||
}
|
||||
if let Some(db_path) = args.db_path {
|
||||
config.db_path = db_path;
|
||||
}
|
||||
|
||||
// Override timeout if specified
|
||||
if let Some(timeout_secs) = args.timeout {
|
||||
if let baobab_actor::config::ActorType::Async { ref mut default_timeout_seconds } = config.actor_type {
|
||||
*default_timeout_seconds = timeout_secs;
|
||||
}
|
||||
}
|
||||
|
||||
// Configure logging
|
||||
setup_logging(&config, args.verbose, args.no_timestamp)?;
|
||||
|
||||
info!("🚀 System Actor starting...");
|
||||
info!("Actor ID: {}", config.actor_id);
|
||||
info!("Redis URL: {}", config.redis_url);
|
||||
info!("Database Path: {}", config.db_path);
|
||||
info!("Preserve Tasks: {}", config.preserve_tasks);
|
||||
|
||||
if let Some(timeout) = config.get_default_timeout() {
|
||||
info!("Default Timeout: {:?}", timeout);
|
||||
}
|
||||
|
||||
// Create Rhai engine
|
||||
let engine = create_heromodels_engine();
|
||||
info!("✅ Rhai engine initialized");
|
||||
|
||||
// Create actor configuration for the trait-based interface
|
||||
let mut actor_config = TraitActorConfig::new(
|
||||
config.actor_id.clone(),
|
||||
config.db_path.clone(),
|
||||
config.redis_url.clone(),
|
||||
config.preserve_tasks,
|
||||
);
|
||||
|
||||
// Add timeout configuration for async actor
|
||||
if let Some(timeout) = config.get_default_timeout() {
|
||||
actor_config = actor_config.with_default_timeout(timeout);
|
||||
}
|
||||
|
||||
// Create async actor instance
|
||||
let actor = Arc::new(AsyncActor::default());
|
||||
info!("✅ Async actor instance created");
|
||||
|
||||
// Setup shutdown signal handling
|
||||
let (shutdown_tx, shutdown_rx) = mpsc::channel(1);
|
||||
|
||||
// Spawn shutdown signal handler
|
||||
let shutdown_tx_clone = shutdown_tx.clone();
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = signal::ctrl_c().await {
|
||||
error!("Failed to listen for shutdown signal: {}", e);
|
||||
return;
|
||||
}
|
||||
info!("🛑 Shutdown signal received");
|
||||
if let Err(e) = shutdown_tx_clone.send(()).await {
|
||||
error!("Failed to send shutdown signal: {}", e);
|
||||
}
|
||||
});
|
||||
|
||||
// Spawn statistics reporter if requested
|
||||
if args.show_stats {
|
||||
let actor_stats = Arc::clone(&actor);
|
||||
tokio::spawn(async move {
|
||||
let mut interval = tokio::time::interval(Duration::from_secs(30));
|
||||
loop {
|
||||
interval.tick().await;
|
||||
let running_count = actor_stats.running_job_count().await;
|
||||
if running_count > 0 {
|
||||
info!("📊 Actor Stats: {} jobs currently running", running_count);
|
||||
} else {
|
||||
info!("📊 Actor Stats: No jobs currently running");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Spawn the actor
|
||||
info!("🔄 Starting actor loop...");
|
||||
let actor_handle = spawn_actor(actor, engine, shutdown_rx);
|
||||
|
||||
// Wait for the actor to complete
|
||||
match actor_handle.await {
|
||||
Ok(Ok(())) => {
|
||||
info!("✅ System Actor shut down gracefully");
|
||||
}
|
||||
Ok(Err(e)) => {
|
||||
error!("❌ System Actor encountered an error: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
Err(e) => {
|
||||
error!("❌ Failed to join actor task: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Setup logging based on configuration and command line arguments
|
||||
fn setup_logging(
|
||||
config: &ActorConfig,
|
||||
verbose: bool,
|
||||
no_timestamp: bool,
|
||||
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let mut builder = env_logger::Builder::new();
|
||||
|
||||
// Determine log level
|
||||
let log_level = if verbose {
|
||||
"debug"
|
||||
} else {
|
||||
&config.logging.level
|
||||
};
|
||||
|
||||
// Set log level
|
||||
builder.filter_level(match log_level.to_lowercase().as_str() {
|
||||
"trace" => log::LevelFilter::Trace,
|
||||
"debug" => log::LevelFilter::Debug,
|
||||
"info" => log::LevelFilter::Info,
|
||||
"warn" => log::LevelFilter::Warn,
|
||||
"error" => log::LevelFilter::Error,
|
||||
_ => {
|
||||
warn!("Invalid log level: {}. Using 'info'", log_level);
|
||||
log::LevelFilter::Info
|
||||
}
|
||||
});
|
||||
|
||||
// Configure timestamps
|
||||
let show_timestamps = !no_timestamp && config.logging.timestamps;
|
||||
if !show_timestamps {
|
||||
builder.format_timestamp(None);
|
||||
}
|
||||
|
||||
builder.init();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::io::Write;
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
#[test]
|
||||
fn test_config_validation() {
|
||||
let config_toml = r#"
|
||||
actor_id = "test_system"
|
||||
redis_url = "redis://localhost:6379"
|
||||
db_path = "/tmp/test_db"
|
||||
|
||||
[actor_type]
|
||||
type = "async"
|
||||
default_timeout_seconds = 600
|
||||
|
||||
[logging]
|
||||
level = "info"
|
||||
"#;
|
||||
|
||||
let mut temp_file = NamedTempFile::new().unwrap();
|
||||
temp_file.write_all(config_toml.as_bytes()).unwrap();
|
||||
|
||||
let config = ActorConfig::from_file(temp_file.path()).unwrap();
|
||||
assert!(!config.is_sync());
|
||||
assert!(config.is_async());
|
||||
assert_eq!(config.actor_id, "test_system");
|
||||
assert_eq!(config.get_default_timeout(), Some(Duration::from_secs(600)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sync_config_rejection() {
|
||||
let config_toml = r#"
|
||||
actor_id = "test_system"
|
||||
redis_url = "redis://localhost:6379"
|
||||
db_path = "/tmp/test_db"
|
||||
|
||||
[actor_type]
|
||||
type = "sync"
|
||||
|
||||
[logging]
|
||||
level = "info"
|
||||
"#;
|
||||
|
||||
let mut temp_file = NamedTempFile::new().unwrap();
|
||||
temp_file.write_all(config_toml.as_bytes()).unwrap();
|
||||
|
||||
let config = ActorConfig::from_file(temp_file.path()).unwrap();
|
||||
assert!(config.is_sync());
|
||||
assert!(!config.is_async());
|
||||
// This would be rejected in main() function
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_timeout_override() {
|
||||
let config_toml = r#"
|
||||
actor_id = "test_system"
|
||||
redis_url = "redis://localhost:6379"
|
||||
db_path = "/tmp/test_db"
|
||||
|
||||
[actor_type]
|
||||
type = "async"
|
||||
default_timeout_seconds = 300
|
||||
"#;
|
||||
|
||||
let mut temp_file = NamedTempFile::new().unwrap();
|
||||
temp_file.write_all(config_toml.as_bytes()).unwrap();
|
||||
|
||||
let mut config = ActorConfig::from_file(temp_file.path()).unwrap();
|
||||
assert_eq!(config.get_default_timeout(), Some(Duration::from_secs(300)));
|
||||
|
||||
// Test timeout override
|
||||
if let baobab_actor::config::ActorType::Async { ref mut default_timeout_seconds } = config.actor_type {
|
||||
*default_timeout_seconds = 600;
|
||||
}
|
||||
assert_eq!(config.get_default_timeout(), Some(Duration::from_secs(600)));
|
||||
}
|
||||
}
|
95
_archive/core/actor/cmd/worker.rs
Normal file
95
_archive/core/actor/cmd/worker.rs
Normal file
@@ -0,0 +1,95 @@
|
||||
use clap::Parser;
|
||||
use baobab_actor::engine::create_heromodels_engine;
|
||||
use baobab_actor::spawn_rhai_actor;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
struct Args {
|
||||
/// Actor ID for identification
|
||||
#[arg(short, long)]
|
||||
actor_id: String,
|
||||
|
||||
/// Redis URL
|
||||
#[arg(short, long, default_value = "redis://localhost:6379")]
|
||||
redis_url: String,
|
||||
|
||||
/// Preserve task details after completion (for benchmarking)
|
||||
#[arg(long, default_value = "false")]
|
||||
preserve_tasks: bool,
|
||||
|
||||
/// Root directory for engine database
|
||||
#[arg(long, default_value = "actor_rhai_temp_db")]
|
||||
db_path: String,
|
||||
|
||||
/// Disable timestamps in log output
|
||||
#[arg(long, help = "Remove timestamps from log output")]
|
||||
no_timestamp: bool,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let args = Args::parse();
|
||||
|
||||
// Configure env_logger with or without timestamps
|
||||
if args.no_timestamp {
|
||||
env_logger::Builder::from_default_env()
|
||||
.format_timestamp(None)
|
||||
.init();
|
||||
} else {
|
||||
env_logger::init();
|
||||
}
|
||||
|
||||
|
||||
log::info!("Rhai Actor (binary) starting with performance-optimized engine.");
|
||||
log::info!(
|
||||
"Actor ID: {}, Redis: {}",
|
||||
args.actor_id,
|
||||
args.redis_url
|
||||
);
|
||||
|
||||
let mut engine = create_heromodels_engine();
|
||||
|
||||
// Performance optimizations for benchmarking
|
||||
engine.set_max_operations(0); // Unlimited operations for performance testing
|
||||
engine.set_max_expr_depths(0, 0); // Unlimited expression depth
|
||||
engine.set_max_string_size(0); // Unlimited string size
|
||||
engine.set_max_array_size(0); // Unlimited array size
|
||||
engine.set_max_map_size(0); // Unlimited map size
|
||||
|
||||
// Enable full optimization for maximum performance
|
||||
engine.set_optimization_level(rhai::OptimizationLevel::Full);
|
||||
|
||||
log::info!("Engine configured for maximum performance");
|
||||
|
||||
// Create shutdown channel (for graceful shutdown, though not used in benchmarks)
|
||||
let (_shutdown_tx, shutdown_rx) = mpsc::channel::<()>(1);
|
||||
|
||||
// Spawn the actor
|
||||
let actor_handle = spawn_rhai_actor(
|
||||
args.actor_id,
|
||||
args.db_path,
|
||||
engine,
|
||||
args.redis_url,
|
||||
shutdown_rx,
|
||||
args.preserve_tasks,
|
||||
);
|
||||
|
||||
// Wait for the actor to complete
|
||||
match actor_handle.await {
|
||||
Ok(result) => match result {
|
||||
Ok(_) => {
|
||||
log::info!("Actor completed successfully");
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Actor failed: {}", e);
|
||||
Err(e)
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
log::error!("Actor task panicked: {}", e);
|
||||
Err(Box::new(e) as Box<dyn std::error::Error + Send + Sync>)
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user