Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ActorRef<T> where T: Into<TMessage> that underlying ActorCell accepts #305

Closed
anabyv042 opened this issue Dec 22, 2024 · 2 comments
Closed
Labels
enhancement New feature or request

Comments

@anabyv042
Copy link
Contributor

Is your feature request related to a problem? Please describe.
Hi! I am trying to achieve some kind of isolation in my actor system, where the actors sending messages to other actors don't know about the receiver's message type but only know that it can accept messages of type T. For example:
image
In this case I would want the Actor1 only to send messages A to Actor3, and Actor2 only to send messages B. This way I could seamlessly change implementation of Actor3 (for example, switch Actor3.1 and Actor3.2) without changing anything about Actor1 and Actor2.

Describe the solution you'd like
It would be great if I could create ActorRef<A> and ActorRef<B> to pass it to Actors that are supposed to talk to Actor3. Actor3's message can implement From<A> and From<B>, so before calling send_message it would be able to cast the incoming message to the actual message type Actor3 could receive. I think currently it is not possible because of the runtime type check in send_message:
if self.id.is_local() && self.type_id != std::any::TypeId::of::<TMessage>()

Describe alternatives you've considered
One alternative thing that is easy to do is to create a trait wrapping the ActorRef and use it instead but this seems hacky.

pub trait MyActorRef<T> {
    fn send(&self, msg: T) -> anyhow::Result<()>;
}

impl<T, Q> MyActorRef<T> for ActorRef<Q> where T: Into<Q>, Q: Message {
    fn send(&self, msg: T) -> anyhow::Result<()> {
        self.send_message(msg.into())?;
        Ok(())
    }
}

Please let me know if there's already a good way to do this and I missed it. Thanks for your help!

@anabyv042 anabyv042 added the enhancement New feature or request label Dec 22, 2024
@slawlor
Copy link
Owner

slawlor commented Dec 23, 2024

This is a really neat idea! I think we would need to introduce a new type however, something like FromActorRef<T> (the naming isn't final obviously). But yeah, I don't think this is something that can be done directly on an actor ref, but should be something we can add as a wrapper. It would be handy, since you could do stuff like

let actor: ActorRef<A>: ...;

let type_b: FromActorRef<B> = actor.clone().from();
let type_c: FromActorRef<C> = actor.clone().from();

where they each have their own discrete type.

@anabyv042
Copy link
Contributor Author

cool, thanks! I will see if I can make a PR for this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants