7 ms·
Show HN: Kameo – Fault-tolerant async actors built on Tokio
Hi HN,
I’m excited to share Kameo, a lightweight Rust library that helps you build fault-tolerant, distributed, and asynchronous actors. If you're working on distributed systems, microservices, or real-time applications, Kameo offers a simple yet powerful API for handling concurrency, panic recovery, and remote messaging between nodes.
Key Features:
- Async Rust: Each actor runs as a separate Tokio task, making concurrency management simple.
- Remote Messaging: Seamlessly send messages to actors across different nodes.
- Supervision and Fault Tolerance: Create self-healing systems with actor hierarchies.
- Backpressure Support: Supports bounded and unbounded mpsc messaging.
I built Kameo because I wanted a more intuitive, scalable solution for distributed Rust applications. I’d love feedback from the HN community and contributions from anyone interested in Rust and actor-based systems.
Check out the project on GitHub: https://github.com/tqwewe/kameo https://github.com/tqwewe/kameo
Looking forward to hearing your thoughts!
- __erik 2y agoThis looks really nice! Curious if its running in production anywhere
- qwertox 2y agoI agree, really nice syntax. There's a limitation mentioned in the docs: While messages are processed sequentially within a single actor, Kameo allows for concurrent processing across multiple actors. which is justified via This [sequential processing] model also ensures that messages are processed in the order they are received, which can be critical for maintaining consistency and correctness in certain applications. I agree to this and it gives the library a well defined use. Docs and examples are well made.
- zackangelo 2y agoThis limitation is common to most implementations of the actor model. In fact, I think a lot of people would consider it a feature, not a limitation because it allows you to reason about your concurrent behavior in a more straightforward way.
- tqwewe 2y agoThank you for the lovely feedback! Happy to hear this. Will continue improving documentation, adding more examples to code docs, etc.
- rad_gruchalski 2y ago> There's a limitation It’s a feature.
- tqwewe 2y agoNot yet, however I hope to answer with yes soon. I'm using kameo heavily in a startup I'm building (oddselite.app). Hopefully will be released shortly for this to be a yes. But as of now, it's still quite a new library and the API has gone through many breaking changes to get where its at now
- m00x 2y agoWhat are the advantages and disadvantages vs using Actix or Ractor?
- deleted 2y ago[deleted]
- mtndew4brkfst 2y agoPSA: Actix (not Actix-web) is fairly inactive - one of the maintainers informally said not to use it for any new projects during one of this year's RustConf chats.
- snowboarder63 2y agohttps://discord.com/channels/734893811884621927/1270439672627331202/1283493019403681814 https://discord.com/channels/734893811884621927/127043967262...
- stusmall 2y agoThe actix crate is deprecated. I looked on their site and repo and couldn't find an official announcement of deprecation but here is a link to what the lead said when I reached out with questions a few months ago: https://discord.com/channels/771444961383153695/771447523956883466/1204823567452217365 https://discord.com/channels/771444961383153695/771447523956... EDIT: Tangent, but if anyone has experience making deterministic actor model systems that can be run under a property test I'd love to know more. It would make an amazing blog post even if it would have a very narrow audience
- status_quo69 2y agoI actually went through this exact exercise recently, but this library didn't show up in my searches for a good rust actor framework, so take that with a grain of salt. It looks very similar to the interface provided by actix at first blush, not sure how supervision works. My take is that most of these frameworks tend to solve with the same(ish) solution, so pick the one that has the best api. I liked ractor, although not having &mut self eventually wore me down. I swapped a small side project to use Stakker instead and while at first the macros intimidated me, the implementation really impressed me in terms of performance and API characteristics. It really feels like there's just enough there and no more.
- TheMagicHorsey 2y agoLooks really nice. But sometimes when I see projects like this in other languages, I think, are you sure you don't want to use Erlang or something else on the BEAM runtime and just call Rust or C via their NIFs? I used Erlang about a decade ago, and even then it was so robust, easy to use, and mature. Granted you have to offload anything performance-sensitive to native functions but the interface was straightforward. In the Erlang community back then there were always legends about how Whatsapp had only 10 people and 40 servers to serve 1 Billion customers. Probably an exaggeration, but I could totally see it being true. That's how well thought out and robust it was. Having said all that, I don't mean to diminish your accomplishment here. This is very cool!
- greenavocado 2y agoMassive context switching and type checking on Erlang is inferior.
- hansonkd 2y agoI think a lot of issues BEAM was trying to solve were solved by processors getting bigger and more cores. BEAM's benefit 10-20 years ago where that inter-node communication was essentially the same as communicating in the same process. Meaning i could talk to an actor on a different machine the same way as if it was in the same process. These days people just spin up more cores on one machine. Getting good performance out of multi-node erlang is a challenge and only really works if you can host all the servers on one rack to simulate a multi-core machine. The built in distributed part of erlang doesn't work so well in modern VPS / AWS setup, although some try.
- binary132 2y ago“Just spin up more cores on one machine” has a pretty low scale ceiling, don’t you think? What, 96 cores? Maybe a few more on ARM? What do you do when you need thousands or tens of thousands of cores? Well, what I do is think of functions as services, and there are different ways to get that, but BEAM / OTP are surely among them.
- throwawaymaths 2y agoIs this actually distributed? I see no evidence that this can be used in conjunction with even ipc with builtin features.
- hansonkd 2y agoCheck the examples folder.
- qwertox 2y agohttps://github.com/tqwewe/kameo/blob/main/examples/remote.rs https://github.com/tqwewe/kameo/blob/main/examples/remote.rs // Bootstrap the actor swarm if is_host { ActorSwarm::bootstrap()? .listen_on("/ip4/0.0.0.0/udp/8020/quic-v1".parse()?) .await?; } else { ActorSwarm::bootstrap()?.dial( DialOpts::unknown_peer_id() .address("/ip4/0.0.0.0/udp/8020/quic-v1".parse()?) .build(), ); } let remote_actor_ref = RemoteActorRef::<MyActor>::lookup("my_actor").await?; match remote_actor_ref { Some(remote_actor_ref) => { let count = remote_actor_ref.ask(&Inc { amount: 10 }).send().await?; println!("Incremented! Count is {count}"); } ...
- throwawaymaths 2y agoThanks! It's not in the front page material.
- BWStearns 2y agoLooks very cool. Is there any documentation on how it works for communication over a network? I see the remote/swarm section but is there an overview somewhere?
- tqwewe 2y agoThanks! Its definitely missing, I'll need to add that perhaps to the kameo book. Its using libp2p under the hood with Kademlia distributed hash table for actor registrations.
- assassinator42 2y ago[dead]
- kazinator 2y agoYeah how about something much older. I vote for Lode Runner.
- deleted 2y ago[deleted]
- fuddle 2y agoLooks good, it would be great to see more examples in the docs.
- tqwewe 2y agoThanks! Definitely agree with you, I'll create an issue for this
- wildlogic 2y agoHi - any documentation regarding actor registration? Is there a conventional way to inform a remote actor about a new actor? Would this be sent in a message? How does the actor.register('name') work? Maybe could be a useful addition to the documentation. Thanks.
- tqwewe 2y agoI've added an indepth section to the kameo book about actor registration and lookup, including how it works: https://docs.page/tqwewe/kameo/distributed-actors/registering-looking-up-actors https://docs.page/tqwewe/kameo/distributed-actors/registerin...
- tqwewe 2y agoHi, I'll probably need to add better documentation on the internals of how remote actors work. There's not really any special features for informing other actors when one is registered currently, but you could do this yourself of course via messaging. actor.register('name') works by using a Kademlia DHT behind the scenes. This is implemented thanks to libp2p which handles all the complications of peer to peer connections
- chenzhekl 2y agoCurious, could it be used in wasm? I think it would be really cool if it can be used in browsers.
- tqwewe 2y agoWould be absolutely awesome I agree! But, sadly I don't think tokio really runs in wasm just yet. But I see it being possible some day
- binary132 2y agoWhat I find myself wondering (maybe based on a superficial understanding) is how this is fundamentally different from, or better than grpc, and whether it could be used as an implementation of grpc.
- tqwewe 2y agoIn my experience, setting up gRPC often involves a lot of boilerplate, particularly with code generation when using libraries like Tonic. While gRPC is great for well-defined, schema-driven communication, one of the big advantages of distributed actors in Kameo is that you can communicate with any actor on any node without the need to define a schema upfront. With Kameo, an actor running on another node is simply accessed through a RemoteActorRef, and you can message it the same way you would interact with a local actor. This flexibility allows you to avoid the overhead of schema management while still achieving seamless communication across nodes, making the system more dynamic and less rigid compared to gRPC.
- hi_hi 2y agoCan someone provide some context on what an "actor" is here. It's the first time I've come across the term used like this.
- msaltz 2y agohttps://en.m.wikipedia.org/wiki/Actor_model https://en.m.wikipedia.org/wiki/Actor_model
- fermigier 2y ago43 years of actors: a taxonomy of actor models and their key properties (2016) From the abstract: The Actor Model is a message passing concurrency model that was originally proposed by Hewitt et al. in 1973. It is now 43 years later and since then researchers have explored a plethora of variations on this model. This paper presents a history of the Actor Model throughout those years. The goal of this paper is not to provide an exhaustive overview of every actor system in existence but rather to give an overview of some of the exemplar languages and libraries that influenced the design and rationale of other actor systems throughout those years. This paper therefore shows that most actor systems can be roughly classified into four families, namely: Classic Actors, Active Objects, Processes and Communicating Event-Loops. -> http://soft.vub.ac.be/Publications/2016/vub-soft-tr-16-11.pdf http://soft.vub.ac.be/Publications/2016/vub-soft-tr-16-11.pd...
- rishav_sharan 2y agolikely dumb question, but can this allow me to build trivial concurrent & parallel local apps? being able to parallelize the load across all the cores is important to me.
- tqwewe 2y agoUnder the hood it uses tokio runtime. So as long as you enable `rt-multi-thread` feature flag in tokio, and use `#[tokio::main]`, then yes! Actors can run on multiple threads. By default tokio uses worker threads, equal to the number of threads on your machine. In kameo, all actors run in a `tokio::spawn` task.
- Fiahil 2y agoWhat's the reason for using Async for an Actor framework ? They run in separate tasks / threads anyway and they are cpu-bound. So, why would it be necessary to make them async ?
- tqwewe 2y agoIn the case of tokio, multiple actors can run on a single thread. Tokio uses a worker pool of threads equal to the number of cores on your system. So spawning a new actor will run amongs other actors. This lets us perform io operations in an actor, such as http connection, and progress other actors whilst waiting for a response. Kameo does have a `spawn_in_thread` function for CPU bound actors if needed.
- Fiahil 2y ago> multiple actors can run on a single thread. Right. It's not a very widespread use case, to be honest. You'd find that most would be N actors for M threads (where N <= M ; an Actor in itself is never shared among multiple threads [So `Send` and not `Sync`, in theory] - an inner message handler _could_ have parallel processing but that's up to the user) I think you should assume in Kameo that every Actor's message handler is going to be CPU-bound. For example, it means that your internal message dispatch and Actor management should be on a separate loop from the User's `async fn handle`. I don't know if it's already the case, but it's an important consideration for your design. Nice library, BTW, I think it checks all the marks and I like your design. I've tried most of them but could not find one that I liked and/or that would not have a fatal design flaw (like async_traits, ...) :) PS : Multi-threaded tokio runtime should be the default. Nobody wants a single-threaded actor runtime. It should be in capital letters in the readme.
- kdps 2y ago> Right. It's not a very widespread use case, to be honest. You'd find that most would be N actors for M threads (where N <= M What makes you think that? Having a large number of actors per thread is by far the most important use case. The Actor model is commonly used in communication systems where there are hundreds of thousands of actors per machine (often one for every single user). In this context, Actors are typically extremely lightweight and not CPU-bound. Instead, they mostly focus on network I/O and are often idle, waiting for messages to arrive or be sent.
- 10xalphadev 2y ago"in Tokio" would be even more non-ambiguous.