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

Feature request: utility to call the same actor with multiple messages #111

Open
msparkles opened this issue May 12, 2023 · 8 comments
Open
Labels
enhancement New feature or request

Comments

@msparkles
Copy link

We have written up a (crude) utility function to send multiple messages to the same actor and receive the response with a mpsc channel.

This is mainly to minimize overhead.

Is it possible to include such feature in ractor?

Here's my implementation. One big flaw is that this requires making another message type for MpscSender instead of using RpcReplyPort

pub async fn call_multi<TMessage, TReply, TMsgBuilder>(
    actor: &ActorCell,
    msg_builder: TMsgBuilder,
    size: usize,
) -> Result<Vec<TReply>, MessagingErr<TMessage>>
where
    TMessage: Message,
    TMsgBuilder: FnOnce(MpscSender<TReply>) -> Vec<TMessage>,
{
    let (tx, mut rx) = concurrency::mpsc_bounded(size);
    let msgs = msg_builder(tx);

    for msg in msgs {
        actor.send_message::<TMessage>(msg)?;
    }

    let mut replies = Vec::with_capacity(size);

    // wait for the reply
    while let Some(result) = rx.recv().await {
        replies.push(result);
    }

    Ok(replies)
}
@slawlor
Copy link
Owner

slawlor commented May 12, 2023

Couldn't you use the existing multi_call and give an array of the same actor? Wouldn't that achieve the same result here?

I think there's definitely a use-case for having a MultiReplyPort or something, so instead of a single result, you could get a stream of results for example. But normally that's not something present in Erlang's OTP, and we'd probably build a different pattern for it when needed. As an example, send a cast with an argument of the reply actor, and then the caller sends N messages back to the caller. But it won't block the same way as an RPC.

@msparkles
Copy link
Author

We transitioned from Riker-rs to ractor just now. We made this code because in riker, calling the actor a bunch of times and getting the results (internally via a lot of Oneshot's, just like ractor) was slow, so we made one that utilizes a mpsc channel to make it faster. (And it did improve efficiency there!)

We're not certain that this approach would necessarily be faster in ractor, but generally mpsc seems to fit better than creating a lot of oneshot's for when you have multiple messages with each a response.

Maybe we could make a benchmark, hm.

@msparkles
Copy link
Author

And also, we're not sure if multi_call would help here, since the messages are different.

@slawlor
Copy link
Owner

slawlor commented May 15, 2023

How would you have a mpsc reply port if the input messages are different, therefore likely resulting in different reply types? Unless you have each message have the same return type, which then is quite flaky to provide something at a framework level, I don't see how you could make this work.

We could add a multiple-reply port, but I don't see a strong reason to do it yet (personally).

@msparkles
Copy link
Author

msparkles commented May 16, 2023

The messages are different as in they each have different parameters, specifically different parameters in an Enum.

The replies are the same way, different parameters in the same type as other replies.

We meant that the message values are different, not the types, sorry for the confusion.

@msparkles
Copy link
Author

The messages also have the same enum kind, they're all the same kind just different parameters.

@slawlor
Copy link
Owner

slawlor commented May 16, 2023

We're not certain that this approach would necessarily be faster in ractor, but generally mpsc seems to fit better than creating a lot of oneshot's for when you have multiple messages with each a response.

From my point of view, this would be the only reason to add what you're requesting here. It would require a decent amount of support changes in the proc macros of ractor_cluster I think, so i'm hesitant to do it. If you however wish to put up a PR of what it might look like I'm open to considering it! Thanks :)

@msparkles
Copy link
Author

Got it :) We might work on it when we have time and motivation!

@slawlor slawlor added the enhancement New feature or request label May 19, 2023
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