remove local deps paths
This commit is contained in:
		
							
								
								
									
										157
									
								
								_archive/dispatcher/cmd/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								_archive/dispatcher/cmd/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,157 @@
 | 
			
		||||
# Rhai Client Binary
 | 
			
		||||
 | 
			
		||||
A command-line client for executing Rhai scripts on remote workers via Redis.
 | 
			
		||||
 | 
			
		||||
## Binary: `client`
 | 
			
		||||
 | 
			
		||||
### Installation
 | 
			
		||||
 | 
			
		||||
Build the binary:
 | 
			
		||||
```bash
 | 
			
		||||
cargo build --bin client --release
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Usage
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
# Basic usage - requires caller and circle keys
 | 
			
		||||
client --caller-key <CALLER_KEY> --circle-key <CIRCLE_KEY>
 | 
			
		||||
 | 
			
		||||
# Execute inline script
 | 
			
		||||
client -c <CALLER_KEY> -k <CIRCLE_KEY> --script "print('Hello World!')"
 | 
			
		||||
 | 
			
		||||
# Execute script from file
 | 
			
		||||
client -c <CALLER_KEY> -k <CIRCLE_KEY> --file script.rhai
 | 
			
		||||
 | 
			
		||||
# Use specific worker (defaults to circle key)
 | 
			
		||||
client -c <CALLER_KEY> -k <CIRCLE_KEY> -w <WORKER_KEY> --script "2 + 2"
 | 
			
		||||
 | 
			
		||||
# Custom Redis and timeout
 | 
			
		||||
client -c <CALLER_KEY> -k <CIRCLE_KEY> --redis-url redis://localhost:6379/1 --timeout 60
 | 
			
		||||
 | 
			
		||||
# Remove timestamps from logs
 | 
			
		||||
client -c <CALLER_KEY> -k <CIRCLE_KEY> --no-timestamp
 | 
			
		||||
 | 
			
		||||
# Increase verbosity
 | 
			
		||||
client -c <CALLER_KEY> -k <CIRCLE_KEY> -v --script "debug_info()"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Command-Line Options
 | 
			
		||||
 | 
			
		||||
| Option | Short | Default | Description |
 | 
			
		||||
|--------|-------|---------|-------------|
 | 
			
		||||
| `--caller-key` | `-c` | **Required** | Caller public key (your identity) |
 | 
			
		||||
| `--circle-key` | `-k` | **Required** | Circle public key (execution context) |
 | 
			
		||||
| `--worker-key` | `-w` | `circle-key` | Worker public key (target worker) |
 | 
			
		||||
| `--redis-url` | `-r` | `redis://localhost:6379` | Redis connection URL |
 | 
			
		||||
| `--script` | `-s` | | Rhai script to execute |
 | 
			
		||||
| `--file` | `-f` | | Path to Rhai script file |
 | 
			
		||||
| `--timeout` | `-t` | `30` | Timeout for script execution (seconds) |
 | 
			
		||||
| `--no-timestamp` | | `false` | Remove timestamps from log output |
 | 
			
		||||
| `--verbose` | `-v` | | Increase verbosity (stackable) |
 | 
			
		||||
 | 
			
		||||
### Execution Modes
 | 
			
		||||
 | 
			
		||||
#### Inline Script Execution
 | 
			
		||||
```bash
 | 
			
		||||
# Execute a simple calculation
 | 
			
		||||
client -c caller_123 -k circle_456 -s "let result = 2 + 2; print(result);"
 | 
			
		||||
 | 
			
		||||
# Execute with specific worker
 | 
			
		||||
client -c caller_123 -k circle_456 -w worker_789 -s "get_user_data()"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Script File Execution
 | 
			
		||||
```bash
 | 
			
		||||
# Execute script from file
 | 
			
		||||
client -c caller_123 -k circle_456 -f examples/data_processing.rhai
 | 
			
		||||
 | 
			
		||||
# Execute with custom timeout
 | 
			
		||||
client -c caller_123 -k circle_456 -f long_running_script.rhai -t 120
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Interactive Mode
 | 
			
		||||
```bash
 | 
			
		||||
# Enter interactive REPL mode (when no script or file provided)
 | 
			
		||||
client -c caller_123 -k circle_456
 | 
			
		||||
 | 
			
		||||
# Interactive mode with verbose logging
 | 
			
		||||
client -c caller_123 -k circle_456 -v --no-timestamp
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Interactive Mode
 | 
			
		||||
 | 
			
		||||
When no script (`-s`) or file (`-f`) is provided, the client enters interactive mode:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
🔗 Starting Rhai Client
 | 
			
		||||
📋 Configuration:
 | 
			
		||||
   Caller Key: caller_123
 | 
			
		||||
   Circle Key: circle_456
 | 
			
		||||
   Worker Key: circle_456
 | 
			
		||||
   Redis URL: redis://localhost:6379
 | 
			
		||||
   Timeout: 30s
 | 
			
		||||
 | 
			
		||||
✅ Connected to Redis at redis://localhost:6379
 | 
			
		||||
🎮 Entering interactive mode
 | 
			
		||||
Type Rhai scripts and press Enter to execute. Type 'exit' or 'quit' to close.
 | 
			
		||||
rhai> let x = 42; print(x);
 | 
			
		||||
Status: completed
 | 
			
		||||
Output: 42
 | 
			
		||||
rhai> exit
 | 
			
		||||
👋 Goodbye!
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Configuration Examples
 | 
			
		||||
 | 
			
		||||
#### Development Usage
 | 
			
		||||
```bash
 | 
			
		||||
# Simple development client
 | 
			
		||||
client -c dev_user -k dev_circle
 | 
			
		||||
 | 
			
		||||
# Development with clean logs
 | 
			
		||||
client -c dev_user -k dev_circle --no-timestamp -v
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Production Usage
 | 
			
		||||
```bash
 | 
			
		||||
# Production client with specific worker
 | 
			
		||||
client \
 | 
			
		||||
  --caller-key prod_user_123 \
 | 
			
		||||
  --circle-key prod_circle_456 \
 | 
			
		||||
  --worker-key prod_worker_789 \
 | 
			
		||||
  --redis-url redis://redis-cluster:6379/0 \
 | 
			
		||||
  --timeout 300 \
 | 
			
		||||
  --file production_script.rhai
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Batch Processing
 | 
			
		||||
```bash
 | 
			
		||||
# Process multiple scripts
 | 
			
		||||
for script in scripts/*.rhai; do
 | 
			
		||||
  client -c batch_user -k batch_circle -f "$script" --no-timestamp
 | 
			
		||||
done
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Key Concepts
 | 
			
		||||
 | 
			
		||||
- **Caller Key**: Your identity - used for authentication and tracking
 | 
			
		||||
- **Circle Key**: Execution context - defines the environment/permissions
 | 
			
		||||
- **Worker Key**: Target worker - which worker should execute the script (defaults to circle key)
 | 
			
		||||
 | 
			
		||||
### Error Handling
 | 
			
		||||
 | 
			
		||||
The client provides clear error messages for:
 | 
			
		||||
- Missing required keys
 | 
			
		||||
- Redis connection failures
 | 
			
		||||
- Script execution timeouts
 | 
			
		||||
- Worker unavailability
 | 
			
		||||
- Script syntax errors
 | 
			
		||||
 | 
			
		||||
### Dependencies
 | 
			
		||||
 | 
			
		||||
- `rhai_dispatcher`: Core client library for Redis-based script execution
 | 
			
		||||
- `redis`: Redis client for task queue communication
 | 
			
		||||
- `clap`: Command-line argument parsing
 | 
			
		||||
- `env_logger`: Logging infrastructure
 | 
			
		||||
- `tokio`: Async runtime
 | 
			
		||||
							
								
								
									
										207
									
								
								_archive/dispatcher/cmd/dispatcher.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								_archive/dispatcher/cmd/dispatcher.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,207 @@
 | 
			
		||||
use clap::Parser;
 | 
			
		||||
use rhai_dispatcher::{RhaiDispatcher, RhaiDispatcherBuilder};
 | 
			
		||||
use log::{error, info};
 | 
			
		||||
use colored::Colorize;
 | 
			
		||||
use std::io::{self, Write};
 | 
			
		||||
use std::time::Duration;
 | 
			
		||||
 | 
			
		||||
#[derive(Parser, Debug)]
 | 
			
		||||
#[command(author, version, about = "Rhai Client - Script execution client", long_about = None)]
 | 
			
		||||
struct Args {
 | 
			
		||||
    /// Caller public key (caller ID)
 | 
			
		||||
    #[arg(short = 'c', long = "caller-key", help = "Caller public key (your identity)")]
 | 
			
		||||
    caller_id: String,
 | 
			
		||||
 | 
			
		||||
    /// Circle public key (context ID)
 | 
			
		||||
    #[arg(short = 'k', long = "circle-key", help = "Circle public key (execution context)")]
 | 
			
		||||
    context_id: String,
 | 
			
		||||
 | 
			
		||||
    /// Worker public key (defaults to circle public key if not provided)
 | 
			
		||||
    #[arg(short = 'w', long = "worker-key", help = "Worker public key (defaults to circle key)")]
 | 
			
		||||
    worker_id: String,
 | 
			
		||||
 | 
			
		||||
    /// Redis URL
 | 
			
		||||
    #[arg(short, long, default_value = "redis://localhost:6379", help = "Redis connection URL")]
 | 
			
		||||
    redis_url: String,
 | 
			
		||||
 | 
			
		||||
    /// Rhai script to execute
 | 
			
		||||
    #[arg(short, long, help = "Rhai script to execute")]
 | 
			
		||||
    script: Option<String>,
 | 
			
		||||
 | 
			
		||||
    /// Path to Rhai script file
 | 
			
		||||
    #[arg(short, long, help = "Path to Rhai script file")]
 | 
			
		||||
    file: Option<String>,
 | 
			
		||||
 | 
			
		||||
    /// Timeout for script execution (in seconds)
 | 
			
		||||
    #[arg(short, long, default_value = "30", help = "Timeout for script execution in seconds")]
 | 
			
		||||
    timeout: u64,
 | 
			
		||||
 | 
			
		||||
    /// Increase verbosity (can be used multiple times)
 | 
			
		||||
    #[arg(short, long, action = clap::ArgAction::Count, help = "Increase verbosity (-v for debug, -vv for trace)")]
 | 
			
		||||
    verbose: u8,
 | 
			
		||||
 | 
			
		||||
    /// 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>> {
 | 
			
		||||
    let args = Args::parse();
 | 
			
		||||
 | 
			
		||||
    // Configure logging based on verbosity level
 | 
			
		||||
    let log_config = match args.verbose {
 | 
			
		||||
        0 => "warn,rhai_dispatcher=warn",
 | 
			
		||||
        1 => "info,rhai_dispatcher=info",
 | 
			
		||||
        2 => "debug,rhai_dispatcher=debug",
 | 
			
		||||
        _ => "trace,rhai_dispatcher=trace",
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    std::env::set_var("RUST_LOG", log_config);
 | 
			
		||||
    
 | 
			
		||||
    // 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();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if args.verbose > 0 {
 | 
			
		||||
        info!("🔗 Starting Rhai Dispatcher");
 | 
			
		||||
        info!("📋 Configuration:");
 | 
			
		||||
        info!("   Caller ID: {}", args.caller_id);
 | 
			
		||||
        info!("   Context ID: {}", args.context_id);
 | 
			
		||||
        info!("   Worker ID: {}", args.worker_id);
 | 
			
		||||
        info!("   Redis URL: {}", args.redis_url);
 | 
			
		||||
        info!("   Timeout: {}s", args.timeout);
 | 
			
		||||
        info!("");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create the Rhai client
 | 
			
		||||
    let client = RhaiDispatcherBuilder::new()
 | 
			
		||||
        .caller_id(&args.caller_id)
 | 
			
		||||
        .worker_id(&args.worker_id)
 | 
			
		||||
        .context_id(&args.context_id)
 | 
			
		||||
        .redis_url(&args.redis_url)
 | 
			
		||||
        .build()?;
 | 
			
		||||
 | 
			
		||||
    if args.verbose > 0 {
 | 
			
		||||
        info!("✅ Connected to Redis at {}", args.redis_url);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Determine execution mode
 | 
			
		||||
    if let Some(script_content) = args.script {
 | 
			
		||||
        // Execute inline script
 | 
			
		||||
        if args.verbose > 0 {
 | 
			
		||||
            info!("📜 Executing inline script");
 | 
			
		||||
        }
 | 
			
		||||
        execute_script(&client, script_content, args.timeout).await?;
 | 
			
		||||
    } else if let Some(file_path) = args.file {
 | 
			
		||||
        // Execute script from file
 | 
			
		||||
        if args.verbose > 0 {
 | 
			
		||||
            info!("📁 Loading script from file: {}", file_path);
 | 
			
		||||
        }
 | 
			
		||||
        let script_content = std::fs::read_to_string(&file_path)
 | 
			
		||||
            .map_err(|e| format!("Failed to read script file '{}': {}", file_path, e))?;
 | 
			
		||||
        execute_script(&client, script_content, args.timeout).await?;
 | 
			
		||||
    } else {
 | 
			
		||||
        // Interactive mode
 | 
			
		||||
        info!("🎮 Entering interactive mode");
 | 
			
		||||
        info!("Type Rhai scripts and press Enter to execute. Type 'exit' or 'quit' to close.");
 | 
			
		||||
        run_interactive_mode(&client, args.timeout, args.verbose).await?;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async fn execute_script(
 | 
			
		||||
    client: &RhaiDispatcher,
 | 
			
		||||
    script: String,
 | 
			
		||||
    timeout_secs: u64,
 | 
			
		||||
) -> Result<(), Box<dyn std::error::Error>> {
 | 
			
		||||
    info!("⚡ Executing script: {:.50}...", script);
 | 
			
		||||
    
 | 
			
		||||
    let timeout = Duration::from_secs(timeout_secs);
 | 
			
		||||
    
 | 
			
		||||
    match client
 | 
			
		||||
        .new_play_request()
 | 
			
		||||
        .script(&script)
 | 
			
		||||
        .timeout(timeout)
 | 
			
		||||
        .await_response()
 | 
			
		||||
        .await
 | 
			
		||||
    {
 | 
			
		||||
        Ok(result) => {
 | 
			
		||||
            info!("✅ Script execution completed");
 | 
			
		||||
            println!("Status: {}", result.status);
 | 
			
		||||
            if let Some(output) = result.output {
 | 
			
		||||
                println!("Output: {}", output);
 | 
			
		||||
            }
 | 
			
		||||
            if let Some(error) = result.error {
 | 
			
		||||
                println!("Error: {}", error);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Err(e) => {
 | 
			
		||||
            error!("❌ Script execution failed: {}", e);
 | 
			
		||||
            return Err(Box::new(e));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async fn run_interactive_mode(
 | 
			
		||||
    client: &RhaiDispatcher,
 | 
			
		||||
    timeout_secs: u64,
 | 
			
		||||
    verbose: u8,
 | 
			
		||||
) -> Result<(), Box<dyn std::error::Error>> {
 | 
			
		||||
    let timeout = Duration::from_secs(timeout_secs);
 | 
			
		||||
    
 | 
			
		||||
    loop {
 | 
			
		||||
        print!("rhai> ");
 | 
			
		||||
        io::stdout().flush()?;
 | 
			
		||||
        
 | 
			
		||||
        let mut input = String::new();
 | 
			
		||||
        io::stdin().read_line(&mut input)?;
 | 
			
		||||
        
 | 
			
		||||
        let input = input.trim();
 | 
			
		||||
        
 | 
			
		||||
        if input.is_empty() {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if input == "exit" || input == "quit" {
 | 
			
		||||
            info!("👋 Goodbye!");
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if verbose > 0 {
 | 
			
		||||
            info!("⚡ Executing: {}", input);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        match client
 | 
			
		||||
            .new_play_request()
 | 
			
		||||
            .script(input)
 | 
			
		||||
            .timeout(timeout)
 | 
			
		||||
            .await_response()
 | 
			
		||||
            .await
 | 
			
		||||
        {
 | 
			
		||||
            Ok(result) => {
 | 
			
		||||
                if let Some(output) = result.output {
 | 
			
		||||
                    println!("{}", output.color("green"));
 | 
			
		||||
                }
 | 
			
		||||
                if let Some(error) = result.error {
 | 
			
		||||
                    println!("{}", format!("error: {}", error).color("red"));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            Err(e) => {
 | 
			
		||||
                println!("{}", format!("error: {}", e).red());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        println!(); // Add blank line for readability
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user