HNHacker News
TopNewBestAskShowJobs

snowboarder63

186 karma · joined February 16, 2023

submissionscomments
snowboarder63··on Ractor – a Rust Actor Framework
Honest truth? I didn't Google it first lol. I just checked if there was a crate with the same name and carried on. I only found out about the Ruby ones after I posted on Reddit for the first time. By then it was too late since I had already reserved the crate name and it was being downloaded
snowboarder63··on Ractor – a Rust Actor Framework
I actually have a side project doing this. I mapped an actor Id in ractor to a PID in erlang and used a rust create to implement the network protocol for erlang. I ran out of time on this side project kind of deal but it's like 90% there and can do a full cluster join and send and receive messages between remote actors on nodes.

The crate that helped this is erl_dist. I'd love to open source the code at some point, but it's not quite there yet

snowboarder63··on Ractor – a Rust Actor Framework
Yeah I do lol. It was the big motivation since we were writing more and more rust and missed the concurrency model. Please feel free to ping me for any further questions

It's come a long way since it started and I'm thrilled I can talk about it publicly now and it's usage at Meta (some at least lol).

snowboarder63··on Show HN: Kameo – Fault-tolerant async actors built on Tokio
https://discord.com/channels/734893811884621927/127043967262...
snowboarder63··on Show HN: Kameo – Fault-tolerant async actors built on Tokio
Thanks! I'm happy to see actors getting some solid use in the industry to provide better thread-management safety and remove a lot of concurrency headaches.

Question for you, I was poking around in the codebase and how do you handle your Signal priorities? Like if a link died, and there's 1000 messages in the queue already, or if it's a bounded mailbox, would the link died (or even stop) messages be delayed by that much?

Have you looked into prioritization of those messages such that it's not globally FIFO?

snowboarder63··on Show HN: Kameo – Fault-tolerant async actors built on Tokio
Also ractor is used in production at Meta. (Which I can finally say publicly lol)

Here's the RustConf presentation for anyone interested https://slawlor.github.io/ractor/assets/rustconf2024_present...

snowboarder63··on Show HN: Kameo – Fault-tolerant async actors built on Tokio
While the state is indeed a separate struct in ractor there's actually a good reason for this. It's because the state is constructed by the actor and it's guaranteed that the construction is the state is managed by the startup flow and panic safe.

Imagine opening a socket, if you have a mutable self the caller who is going to spawn that actor needs to open the socket themselves and risk the failure there. Instead of the actor who would eventually be responsible for said socket. This is outlined in our docs the motivation for this. Essentially the actor is responsible for creation of their state and any risks associated with that.

- for the async trait point we actually do support the native async traits without the boxing magic macro. It's a feature you can disable if you so wish but it impacts factories since you can't then box traits with native future returns https://github.com/slawlor/ractor/pull/202

(For transparency I'm the author of ractor)

snowboarder63··on Deploying key transparency at WhatsApp
I did not use ChatGPT to write this - Me lol
snowboarder63··on Deploying key transparency at WhatsApp
So it does indeed even guarantee that the server is acting in a trustworthy manner due to the public auditing scenario. We will shortly be making our audit logs publicly available to show that the verified crypto proof the client performs does indeed match the publicly available records. The academic works SEEMless (https://eprint.iacr.org/2018/607) and Parakeet (https://www.ndss-symposium.org/ndss-paper/parakeet-practical...) jointly outline how this all works from a technical perspective.

While we do maintain the directory, we are held to an honest standard by our audit logs. Should any auditor find invalid records, they can publicly hold us accountable.

snowboarder63··on Deploying key transparency at WhatsApp
WhatsApp announced that they’re adding key transparency to enhance end-to-end encryption verification within their suite of apps. There’s a blog post going into details on the engineering blog including announcing that the core logic for managing an auditable key directory is being open-sourced on Github: https://github.com/facebook/akd
snowboarder63··on Show HN: Ractor – a Rust-based actor framework with clusters and supervisors
Ah yeah we don't have hot-updates like Erlang does (we may never, it depends on how Rust would let us do it). That being said we aren't running on a runtime, so Rust code is native-compiled. You could take down and upgrade a node in a cluster as long as the network protocol doesn't change (or is at least backwards compat), but you wouldn't be able to like upgrade a single actor on a node.
snowboarder63··on Show HN: Ractor – a Rust-based actor framework with clusters and supervisors
Can you give an example of what you're referring to? I don't know of anything limiting memory / cpu / etc in Erlang at least of any individual gen_server. We have the Factory processes which can gracefully loadshed, but that doesn't stop you from having a memory leak.

At least Rust doesn't have a garbage collector, so when the actor is stopped + dropped, it'll cleanup not only it's state but also it's message queue's flushing them so that all memory is released at the time of drop.

snowboarder63··on Show HN: Ractor – a Rust-based actor framework with clusters and supervisors
Not sure what's public here, so let's just say "big", as in 100's+.
snowboarder63··on Show HN: Ractor – a Rust-based actor framework with clusters and supervisors
I mean lunatic runs within Wasm, which isn't the end of the world, but we compile down to native. Lunatic generally seems to want to be the end-all of concurrency but we fit more into an existing Tokio-based environment.

As far as deployment, do you mean like how we came to build this? Or like how you'd actually deploy it...? Because that's really up to the program being built imo

snowboarder63··on Show HN: Ractor – a Rust-based actor framework with clusters and supervisors
That's essentially a process-abort level panic, which then your whole environment would die. Unfortunately there's not much we can do about that. This will catch all unwindable panics however, so that's quite a lot but yeah there's an edge-case.

https://doc.rust-lang.org/std/panic/fn.catch_unwind.html

snowboarder63··on Show HN: Ractor – a Rust-based actor framework with clusters and supervisors
So to your two parts.

1. If you would want independent message handlers, normally we'd just add functions off the state which would be called strait from the message handler's match statement. I.e. something like self.handle_msg_1(message, state, ...). We looked at having multiple handlers but you kind of either get into generic's hell or having to do some kind of ugly proc macro. We figured this left it up to the implementor on how you want to handle it

2. Sequential processing would really be a factory. That would do parallel work of jobs using a basic actor implementation while handling concurrent work limits, job routing, etc. Otherwise you could always spawn inside your actor and like a wait on multiple handles if you wanted, but that gets messy and kind of diverges from the true intent. There is a factory implementation in the base ractor lib, feel free to take a look!

snowboarder63··on Show HN: Ractor – a Rust-based actor framework with clusters and supervisors
If the actor fails, it could have failed mid-mutation so we can't trust the "state" object. This would be the same if we passed in an owned state (rather than a mutable reference) and the handler didn't reply with a new state object. If a failure happens, the state is dropped there too (in Rust). I know it's not exactly how Erlang handles it, but it's a tradeoff we've accepted in this case. We're open to suggestions however!
snowboarder63··on Show HN: Ractor – a Rust-based actor framework with clusters and supervisors
Ah so presently we're using the Tokio scheduler, which does cooperative scheduling not preemptive. We've abstracted pretty much all of our core concurrency primitives to a single module however so the plan is to support future schedulers (perhaps custom) in the future, but that's not the main focus at the moment. However if you have a blocking task, that will utilize a lot of sequential CPU time, the general guidance is to tokio::spawn_blocking(..) in your actor then await the result, so a new dedicated i/o thread will be used and your actor will yield the main scheduler for other workers.
snowboarder63··on Show HN: Ractor – a Rust-based actor framework with clusters and supervisors
Yeah hot upgrades is something we'd love to get to, but probably won't be able to swing in a compiled language. We had worked out something ugly back in the day in a .net style environment (different library at a different job), but it still didn't compare to Erlang's hot upgrade flow.
snowboarder63··on Show HN: Ractor – a Rust-based actor framework with clusters and supervisors
That's really up to you, Rust has great pattern matching imho, rivaling Erlang's for sure, but with some nice syntax upgrades. Additionally in Ractor, RPC's are strong-typed to the reply type, so a `call` in Erlang might result in the wrong type coming back which then you have to handle in your reply pattern matching or crash. This isn't possible in Rust w/ Ractor, since you _know_ the strong type in advance and can't send an incorrect value.
snowboarder63··on Show HN: Ractor – a Rust-based actor framework with clusters and supervisors
Panic's (which can be captured) are captured and will be propagated to the supervisors. That's one of the biggest goals of building this, panics in tasks which have been spawned is a nightmare to deal with
snowboarder63··on Show HN: Ractor – a Rust-based actor framework with clusters and supervisors
Actually I was not familiar with Orleans until now. I think there's probably similar primitives you could build but from my quick 2s read they're solving a higher order problem. Additionally having written an actor lib in the past in .net, I can say they can't match rust for speed but they do have some nice syntax stuff with reflection we can't do.

So it's a tradeoff on stuff like syntactic sugar and speed imo

snowboarder63··on Show HN: Ractor – a Rust-based actor framework with clusters and supervisors
Actually no, I came up with the name independently and only later discovered their lib. I think it's safe to say we diverge a lot in practice though lol