1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//! Simple Executor Example
//!
//! This example demonstrates how to build a basic ColonyOS executor in Rust.
//! The executor registers itself, waits for processes, and handles them.
//!
//! Run with: cargo run --example simple_executor
use colonyos::core::{Executor, Log};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Configuration - in production, load from environment
let colonyname = "dev";
let executor_prvkey = "ddf7f7791208083b6a9ed975a72684f6406a269cfa36f1b1c32045c0a71fff05";
let colony_prvkey = "ba949fa134981372d6da62b6a56f336ab4d843b22c02a4257dcf7d0d73097514";
// Generate executor ID from private key
let executor_id = colonyos::crypto::gen_id(executor_prvkey);
println!("Executor ID: {}", executor_id);
// Create and register the executor
let executor = Executor::new("rust-executor", &executor_id, "cli", colonyname);
match colonyos::add_executor(&executor, executor_prvkey).await {
Ok(e) => println!("Registered executor: {}", e.executorname),
Err(e) => {
// Executor might already exist
println!("Note: {}", e);
}
}
// Approve the executor (requires colony owner key)
match colonyos::approve_executor(colonyname, "rust-executor", colony_prvkey).await {
Ok(_) => println!("Executor approved"),
Err(e) => println!("Note: {}", e),
}
println!("Executor running, waiting for processes...");
println!("Submit a process with: colonies function exec --func echo --args hello --targettype cli");
// Main processing loop
loop {
// Wait for a process with 10 second timeout
match colonyos::assign(colonyname, 10, executor_prvkey).await {
Ok(process) => {
println!("\n=== Assigned Process ===");
println!("Process ID: {}", process.processid);
println!("Function: {}", process.spec.funcname);
println!("Args: {:?}", process.spec.args);
// Log that we started processing
let log = Log {
processid: process.processid.clone(),
colonyname: colonyname.to_string(),
executorname: "rust-executor".to_string(),
message: format!("Processing function: {}", process.spec.funcname),
timestamp: 0,
};
let _ = colonyos::add_log(&log, executor_prvkey).await;
// Handle the function
match process.spec.funcname.as_str() {
"echo" => {
// Echo function: return the first argument
let output = process
.spec
.args
.get(0)
.map(|s| s.clone())
.unwrap_or_else(|| "no input".to_string());
println!("Echoing: {}", output);
// Set output and close successfully
colonyos::set_output(&process.processid, vec![output], executor_prvkey)
.await?;
colonyos::close(&process.processid, executor_prvkey).await?;
println!("Process completed successfully");
}
"add" => {
// Add function: add two numbers
if process.spec.args.len() >= 2 {
let a: i64 = process.spec.args[0].parse().unwrap_or(0);
let b: i64 = process.spec.args[1].parse().unwrap_or(0);
let result = a + b;
println!("{} + {} = {}", a, b, result);
colonyos::set_output(
&process.processid,
vec![result.to_string()],
executor_prvkey,
)
.await?;
colonyos::close(&process.processid, executor_prvkey).await?;
println!("Process completed successfully");
} else {
colonyos::fail(&process.processid, executor_prvkey).await?;
println!("Process failed: add requires 2 arguments");
}
}
"sleep" => {
// Sleep function: sleep for N seconds
let seconds: u64 = process
.spec
.args
.get(0)
.and_then(|s| s.parse().ok())
.unwrap_or(1);
println!("Sleeping for {} seconds...", seconds);
tokio::time::sleep(tokio::time::Duration::from_secs(seconds)).await;
colonyos::set_output(
&process.processid,
vec![format!("Slept for {} seconds", seconds)],
executor_prvkey,
)
.await?;
colonyos::close(&process.processid, executor_prvkey).await?;
println!("Process completed successfully");
}
_ => {
// Unknown function
println!("Unknown function: {}", process.spec.funcname);
colonyos::fail(&process.processid, executor_prvkey).await?;
println!("Process marked as failed");
}
}
}
Err(e) => {
// Check if it's a timeout (expected) or connection error
if e.conn_err() {
eprintln!("Connection error: {}", e);
tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
}
// Timeout is normal - just continue polling
}
}
}
}