Crates.io | freactor |
lib.rs | freactor |
version | 0.1.8 |
source | src |
created_at | 2024-07-30 07:46:20.855617 |
updated_at | 2024-08-12 01:27:41.924519 |
description | A lightweight framework for asynchronous execution flow. |
homepage | https://github.com/Pro-YY/freactor-rs |
repository | https://github.com/Pro-YY/freactor-rs.git |
max_upload_size | |
id | 1319532 |
size | 16,922 |
A lightweight framework for asynchronous execution flow in Rust, designed to be fast, reliable, scalable and easy-to-use.
Freactor is a lightweight and flexible framework designed to manage and execute asynchronous flows in Rust. It provides an easy-to-use API to define and execute asynchronous tasks, making it ideal for building complex workflows and state machines.
Add with cargo command:
cargo add freactor
Or you can add freactor
to your Cargo.toml
:
[dependencies]
freactor = "0.1"
Here's a quick example to get you started:
/* Your async function implementations, and function map here. */
async r1() {}
async r2() {}
async r3() {}
...
async run () {
// 1. Define business flow config
let flow_config = r#"
{
"ExampleTask1": {
"init_step": "r1",
"config": {
"r1": { "edges": ["r2", "r3", "r4"]},
"r2": { "edges": ["r5", "r3"]},
"r3": { "edges": ["r6", "r4"]},
"r4": { "edges": []},
"r5": { "edges": ["r6", "r3"]},
"r6": { "edges": [], "retry": null}
}
}
}
"#.to_string();
// 2. Init freactor with funcs and config
let f = Freactor::new(func_map, flow_config);
// 3. Prepare you workspace arc state, and run your flow later anywhere
let state = Arc::new(Mutex::new(State:new(YOUR_BUSINESS_DATA)))
f.run("ExampleTask1", workspace_state).await;
}
Here are some examples to illustrate how to use freactor for different scenarios:
Example 1: Multi-Threaded Parallel Execution
// run with independent self data(state)
async fn run() {
// function map and flow config here...
let f = Freactor::new(func_map, flow_config);
// multiple flow instance concurrently
let mut shared_vecs: Vec<Arc<Mutex<State>>> = Vec::with_capacity(10);
for i in 0..shared_vecs.capacity() {
let state = State::new(...);
shared_vecs.push(Arc::new(Mutex::new(state)));
}
let mut jset = JoinSet::new();
for v in shared_vecs.clone() {
let fc = f.clone();
jset.spawn(async move {
let _ = fc.run("Task1", v).await;
});
}
while let Some(_res) = jset.join_next().await {}
for v in shared_vecs {
let vec = v.lock().unwrap();
info!("Mutated Vec: {:?}", *vec);
}
}
Example 2: HTTP Web Server Integration
// with web framework, like Axum
// just put freactor in shared server state (Extension/State) and run your task in handler
async fn handle_task_1(Extension(f): Extension<Arc<Freactor>>) -> &'static str {
let v = Arc::new(Mutex::new(State::new(...)));
let _ = f.run("Task1", v).await;
"Hello, World!"
}
async fn main() {
// function map and flow config here...
let f = Freactor::new(func_map, flow_config);
let shared_server_state = Arc::new(f);
let app = Router::new()
.route("/", get(root))
.route("/1", get(handle_task_1))
.route("/2", get(handle_task_2))
.layer(Extension(shared_server_state));
// run our app with hyper, listening globally on port 3000
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}
For detailed API reference, please visit docs.rs.
Welcome contributions from the community! Please read our CONTRIBUTING guide to learn how you can help.
This project is licensed under the MIT License. See the LICENSE file for details.
If you have any questions, feel free to reach out: