15 releases (9 breaking)
new 0.12.0 | Oct 11, 2024 |
---|---|
0.11.0 | Sep 29, 2024 |
0.9.0 | Jun 25, 2024 |
0.3.2 | Mar 31, 2024 |
#850 in Procedural macros
1,619 downloads per month
Used in 2 crates
(via kameo)
54KB
991 lines
Kameo 🎬
What is Kameo
Kameo is a lightweight Rust library for building fault-tolerant, distributed, and asynchronous actors. It allows seamless communication between actors across nodes, providing scalability, backpressure, and panic recovery for robust distributed systems.
Feature Highlights
- Async Rust: Each actor runs as a separate Tokio task, making concurrency easy and efficient.
- Supervision: Link actors to create a fault-tolerant, self-healing actor hierarchy.
- Remote Messaging: Send messages to actors on different nodes seamlessly.
- Panic Safety: Panics are gracefully handled, allowing the system to recover and continue running.
- Backpressure Management: Supports both bounded and unbounded mpsc messaging for handling load effectively.
Use Cases
Kameo is versatile and can be applied in various domains, such as:
- Distributed Microservices: Build resilient microservices that communicate reliably over a distributed network.
- Real-Time Systems: Ideal for building chat systems, multiplayer games, or real-time monitoring dashboards where low-latency communication is essential.
- IoT Devices: Deploy lightweight actors on low-resource IoT devices for seamless networked communication.
Getting Started
Prerequisites
- Rust installed (check rustup for installation instructions)
- A basic understanding of asynchronous programming in Rust
Installation
Add kameo as a dependency in your Cargo.toml
file:
cargo add kameo
Example: Defining an Actor
use kameo::Actor;
use kameo::message::{Context, Message};
use kameo::request::MessageSend;
// Define an actor that will keep a count
#[derive(Actor)]
struct Counter {
count: i64,
}
// Define the message for incrementing the count
struct Inc { amount: i64 }
// Implement how the actor will handle incoming messages
impl Message<Inc> for Counter {
type Reply = i64;
async fn handle(&mut self, msg: Inc, _ctx: Context<'_, Self, Self::Reply>) -> Self::Reply {
self.count += msg.amount;
self.count
}
}
Spawn and message the actor.
// Spawn the actor and get a reference to it
let actor_ref = kameo::spawn(Counter { count: 0 });
// Use the actor reference to send a message and receive a reply
let count = actor_ref.ask(Inc { amount: 42 }).send().await?;
assert_eq!(count, 42);
Distributed Actor Communication
Kameo supports seamless messaging between actors across distributed nodes. This makes it easy to build distributed systems with actors that can communicate over the network.
How Distributed Actors Work
Distributed actors in Kameo are designed to interact with each other as if they were local, but messages are sent over the network. This is achieved through the following steps:
-
Actor Registration: Actors can be registered under a unique name using
ActorRef::register
. Once registered, other actors or systems can look up this actor from a remote node. Under the hood, Kameo uses a Kademlia Distributed Hash Table (DHT), provided by libp2p, to handle actor registration and lookup across nodes in a distributed manner.// On the host node, register the actor let actor_ref = kameo::spawn(MyActor::default()); actor_ref.register("my_actor").await?;
-
Actor Lookup: On remote nodes, actors can look up registered actors using
RemoteActorRef::lookup
. This returns a reference to the remote actor that can be messaged.// On a guest node, lookup the remote actor let remote_actor_ref = RemoteActorRef::<MyActor>::lookup("my_actor").await?;
-
Message Passing: Once the remote actor reference is obtained, you can send messages to it just like with local actors. The message is serialized, sent over the network, deserialized on the remote node, and handled by the actor.
if let Some(remote_actor_ref) = remote_actor_ref { let count = remote_actor_ref.ask(&Inc { amount: 10 }).send().await?; println!("Incremented! Count is {count}"); }
-
Message Registration: In order to send messages between nodes, the message type must implement
Serialize
andDeserialize
. Additionally, it needs to be annotated with the#[remote_message("uuid")]
macro, where theuuid
is a unique identifier for the message type. This UUID helps identify which message implementation to use when sending and receiving messages over the network. It's important to ensure that the UUID does not conflict with other registered messages in your crate.#[remote_message("3b9128f1-0593-44a0-b83a-f4188baa05bf")] impl Message<Inc> for MyActor { type Reply = i64; async fn handle(&mut self, msg: Inc, _ctx: Context<'_, Self, Self::Reply>) -> Self::Reply { self.count += msg.amount as i64; self.count } }
-
Network Protocol: Kameo uses the libp2p library for networking, allowing actors to communicate over a variety of protocols. libp2p uses multiaddresses, which encode different addressing schemes such as TCP/IP, WebSockets, or QUIC. This flexibility allows Kameo to work seamlessly across different network layers.
- Multiaddresses: A multiaddress specifies how to reach a peer using different protocols. For example, a TCP/IP multiaddress might look like this:
/ip4/198.51.100.0/tcp/6543
. Multiaddresses also support peer identity, preventing impersonation during communication, such as/ip4/192.0.2.0/tcp/4321/p2p/QmcEPrat8ShnCph8WjkREzt5CPXF2RwhYxYBALDcLC1iV6
.
Kameo actors use these multiaddresses when communicating across nodes. The
ActorSwarm
component handles networking, allowing actors to register, look up, and send messages to remote actors, abstracting away the underlying complexity.// Bootstrap the actor swarm and listen on a UDP port 8020 ActorSwarm::bootstrap()? .listen_on("/ip4/0.0.0.0/udp/8020/quic-v1".parse()?) .await?;
- Multiaddresses: A multiaddress specifies how to reach a peer using different protocols. For example, a TCP/IP multiaddress might look like this:
See the kameo book for in-depth information on distributed actors in kameo. Additionally, a full example can be found in examples/remote.rs.
Additional Resources
Contributing
Contributions are welcome! Whether you are a beginner or an experienced Rust developer, there are many ways to contribute:
- Report issues or bugs
- Improve documentation
- Submit pull requests for new features or bug fixes
- Suggest new ideas in discussions
Join our community on Discord to connect with fellow contributors!
Support
If you find Kameo useful and would like to support its development, please consider sponsoring me on GitHub. Your support helps me maintain and improve the project!
Thank you for your support! 💖
License
kameo
is dual-licensed under either:
- MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT)
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
at your option.
Home | Features | Use Cases | Get Started | Distributed Actor Communication | Additional Resources | Contributing | Support | License
Dependencies
~0.5–1MB
~21K SLoC