# Task Forge
A flexible and asynchronous task forge for concurrent task execution in Rust. `Task Forge` allows you to spawn tasks, send messages, and handle task outputs efficiently using Tokio channels.
---
## **Table of Contents**
- [Features](#features)
- [Installation](#installation)
- [Usage](#usage)
- [Basic Example](#basic-example)
- [Waiting for Task Creation](#waiting-for-task-creation)
- [Handling Concurrent Tasks](#handling-concurrent-tasks)
- [Error Handling](#error-handling)
- [Documentation](#documentation)
- [License](#license)
---
## **Features**
- Spawn and manage multiple asynchronous tasks.
- Send messages to tasks and receive their outputs.
- Track task states (`Running`, `Closed`).
- Automatically notify when tasks complete or when the forge is cleaned.
- Flexible task creation with support for generic task arguments.
- Customizable error handling using different error handlers.
- Wait for all tasks to end with an optional timeout.
---
## **Installation**
To add `task_forge` to your project, include the following in your `Cargo.toml`:
```toml
[dependencies]
task_forge = "0.1.1" # Replace with the latest version
tokio = { version = "1", features = ["full"] }
```
---
## **Examples**
# Basic Example
Below is a simple example using the `TaskForge` to create and run a basic task:
```rust
use task_forge::{task::TaskTrait, Sender, Receiver, channel, TaskForge, task::TaskInterface};
struct EchoTask;
impl TaskTrait<String, String, String> for EchoTask {
fn begin(
_: String,
mut message_receiver: Receiver<String>,
task_interface: TaskInterface<Output>,
) {
tokio::spawn(async move {
if let Some(input) = message_receiver.recv().await {
task_interface
.output(format!("Echo: {input}"))
.await
.unwrap();
}
});
}
}
#[tokio::main]
async fn main() {
let (task_forge, _) = TaskForge::<String, String>::new();
let task_id = 1;
task_forge.new_task::<EchoTask, _>(task_id, "Hello".to_string()).await.unwrap();
task_forge.send(task_id, "Hello again!".to_string()).await.unwrap();
let mut result_receiver = task_forge.new_result_redirection().await;
let result = result_receiver.recv().await.unwrap();
assert_eq!(result.output.as_ref(), "Echo: Hello again!");
}
```
# Waiting for Task Creation
You can ensure that a task is fully created before sending a message using `wait_for_task_creation`:
```rust
let task_id = 42;
tokio::spawn(async move {
task_forge.wait_for_task_creation(task_id).await.unwrap();
task_forge.send(task_id, "Message after creation".to_string()).await.unwrap();
});
```
Or you can use `wait_and_send` which does the same work:
```rust
let task_id = 42;
tokio::spawn(async move {
task_forge.wait_and_send(task_id, "Message after creation".to_string()).await.unwrap();
});
```
# Handling Concurrent Tasks
You can spawn and manage multiple tasks concurrently:
```rust
struct IncrementTask;
impl TaskTrait<u64, u64, u64> for IncrementTask {
fn begin(
init_val: u64,
mut message_receiver: Receiver<u64>,
task_interface: TaskInterface<u64>,
) {
tokio::spawn(async move {
if let Some(val) = message_receiver.recv().await {
task_interface.output(init_val + val).await.unwrap();
}
});
}
}
for i in 0..5 {
task_forge.new_task::<IncrementTask, _>(i, i).await.unwrap();
task_forge.send(i, 10).await.unwrap();
}
```
---
## **Error Handling**
`task_forge` provides several built-in error handling mechanisms:
- `panic_error_handler`: Panics when an error occurs
- `log_error_handler`: Logs the errors
- `ignore_error_handler`: Silently ignores all errors
To use a custom error handler, pass the appropriate receiver when creating the forge:
```rust
use task_forge::log_error_handler;
let (task_forge, error_receiver) = TaskForge::new();
log_error_handler(error_receiver);
```
You can also create your own error handler by using the error receiver.
## **Licence**
This project is licensed under the MIT Licence. Let me know if you’d like any changes or additions!