From e78d8d1d77b8f1d7f1e08f437321bd233ae2af79 Mon Sep 17 00:00:00 2001
From: 4o1x5 <4o1x5@4o1x5.dev>
Date: Thu, 24 Oct 2024 22:40:48 +0200
Subject: [PATCH] readme: added examples
---
readme.md | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 156 insertions(+), 3 deletions(-)
diff --git a/readme.md b/readme.md
index 3fe8554..9e33632 100644
--- a/readme.md
+++ b/readme.md
@@ -1,5 +1,158 @@
-# A Rabbit-worker & client
+
BunBun-Worker
-A rust crate to work with RPC and nonRPC calls using rabbitmq.
+A multithreaded _panic-safe_ job runner built on the AMQP. Bunbun-worker features RPC and nonRPC calls, and can handle multiple types of messages at a time.
-TODO description...
+> ❗ Disclaimer
+> This crate is still under development, meaning api's may change on every commit...
+
+## Installation
+
+Since this package is not published to crates.io you will need to add it manually to `Cargo.toml`
+
+```toml
+[dependencies]
+bunbun-worker = { git = "https://git.4o1x5.dev/4o1x5/bunbun-worker", version = "0.12" }
+```
+
+or
+
+```toml
+[dependencies]
+bunbun-worker = { git = "https://git.4o1x5.dev/4o1x5/bunbun-worker", branch = "main" }
+```
+
+## Motivation
+
+I have a project called _Mediarose_ in development and I needed a way to have efficient and simple communication between services to kill of circular dependencies.
+
+## Usage
+
+Here is a basic implementation of an RPC job in bunbun-worker
+
+```rust
+// server
+
+// First let's create a state that will be used inside a job.
+// Imagine this holding a database connection, some context that may need to be changed. Anything really
+#[derive(Clone, Debug)]
+pub struct State {
+ pub something: String,
+}
+
+/// Second, let's create a job, with field that can be serialized/deserialized into JSON
+/// This is what the server will receive from a client and will do the job based on these properties
+#[derive(Deserialize, Serialize, Clone, Debug)]
+pub struct EmailJob {
+ send_to: String,
+ contents: String,
+}
+// We also create a result for it, since it's an RPC job
+#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
+pub struct EmailJobResult {
+ contents: String,
+}
+// And an error type so know if the other end errored out, what to do.
+#[derive(Deserialize, Serialize, Clone, Debug)]
+pub enum EmailJobResultError {
+ Errored,
+}
+
+/// After all this we implement a Jobrunner/Taskrunner to the type, so when the listener receives it, it can run this piece of code.
+impl RPCServerTask for EmailJob {
+ type ErroredResult = EmailJobResultError;
+ type Result = EmailJobResult;
+ type State = State;
+ fn run(
+ self,
+ state: Arc>,
+ ) -> futures::prelude::future::BoxFuture<'static, Result>
+ {
+ Box::pin(async move {
+ tracing::info!("Sent email to {}", self.send_to);
+ tokio::time::sleep(Duration::from_secs(2)).await;
+ return Ok(EmailJobResult {
+ contents: self.contents.clone(),
+ });
+ })
+ }
+}
+// Finally, we can define an async main function to run the listener in.
+#[tokio::main]
+async fn main(){
+ // Define a listener, with a hard-limit of 100 jobs at once.
+ let mut listener =
+ BunBunWorker::new(env::var("AMQP_SERVER_URL").unwrap(), 100.into()).await;
+ // Add the defined sturct to the worker
+ listener
+ .add_rpc_consumer::(
+ "email-emailjob-v1.0.0", // queue name
+ "emailjob", // consumer tag
+ Arc::new(Mutex::new(State {
+ something: "test".into(), // putting our state into a Arc> for thread safety
+ })),
+ )
+ .await;
+ tracing::debug!("Starting listener");
+ // Starting the listener
+ listener.start_all_listeners().await;
+}
+```
+
+```rust
+// client
+
+// Define the same structs we did. These are DTO's after all..
+#[derive(Deserialize, Serialize, Clone, Debug)]
+pub struct EmailJob {
+ send_to: String,
+ contents: String,
+}
+#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
+pub struct EmailJobResult {
+ contents: String,
+}
+#[derive(Deserialize, Serialize, Clone, Debug)]
+pub enum EmailJobResultError {
+ Errored,
+}
+// Now we implement the clientside task for it. This reduces generics when defining the calling..
+impl RPCClientTask for EmailJob {
+ type ErroredResult = EmailJobResultError;
+ type Result = EmailJobResult;
+}
+
+#[tokio::main]
+async fn main(){
+// Define a client
+ let mut client = BunBunClient::new(env::var("AMQP_SERVER_URL").unwrap().as_str())
+ .await
+ .unwrap();
+ // Make a call
+ let result = client
+ .rpc_call::(
+ // Define the job
+ EmailJob {
+ send_to: "someone".into(),
+ contents: "something".into(),
+ },
+ "email-emailjob-v1.0.0", // the queue name
+ )
+ .await
+ .unwrap();
+}
+```
+
+## License
+
+Licensed under [GNU AFFERO GENERAL PUBLIC LICENSE](https://www.gnu.org/licenses/agpl-3.0.en.html)
+
+### Contribution
+
+Currently this library does not accept any contributors, as it's hosted on a private registry and git server.
+
+# Credits
+
+This package was made with the help of-
+
+- [This readme template you are reading right now](https://github.com/webern/cargo-readme/blob/master/README.md)
+- [Lapin, an extensive easy to use rabbitmq client](https://crates.io/crates/lapin)