Skip to content

Derived actor from cell#372

Open
Kannen wants to merge 6 commits intoslawlor:mainfrom
Kannen:derived-actor-from-cell
Open

Derived actor from cell#372
Kannen wants to merge 6 commits intoslawlor:mainfrom
Kannen:derived-actor-from-cell

Conversation

@Kannen
Copy link
Copy Markdown
Contributor

@Kannen Kannen commented Jul 19, 2025

This is a proposal for a new feature. I do need it in production right now so I implemented it and I propose it here as I think it can be useful.

It allows actor cells to "provide" valid DerivedActorRef. For example this is the test of this new feature included in this pull request:

    #[tokio::test]
    async fn derived_actor_from_cell() {
        let (sx, mut rx) = crate::concurrency::mpsc_bounded(10);
        let (ar, _) = Actor::spawn(None, TestActor, sx).await.unwrap();
        let cell = ar.get_cell();
        let dar = cell.provide_derived::<i32>().unwrap();
        dar.send_message(42).unwrap();
        assert_eq!(rx.recv().await.unwrap(), Msg::I32(42));
        let dar = cell.provide_derived::<i64>().unwrap();
        dar.send_message(33).unwrap();
        assert_eq!(rx.recv().await.unwrap(), Msg::I64(33));
    }
}

For this to work, implementor of actor must implement a new fonction in Actor:

   fn provide_derived_actor_ref<'a>(
            myself: crate::ActorRef<Msg>,
            request: &mut super::RequestDerived<'a>,
        ) {
            request.provide_derived_actor(myself.get_derived::<i32>());
            request.provide_derived_actor(myself.get_derived::<i64>());
        }

By default this method does nothing, so actor_cell.provide_derived() always return None if the referenced actor does not overrides this method.

In my case I need this because I want to put in groups actors that have different message type but that all can provide the same DerivedActorRef type.

The implementation looks quite unsafe, but this is superficial adaptation of the standard library code used to extract backtraces from errors in nightly.

Comment thread ractor/src/actor/actor_cell.rs Outdated

/// Retrieve the current status of an [super::Actor]
///
/// Returns the [super::Actor]'s current [ActorStatus]
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: This comment is very wrong

@@ -0,0 +1,258 @@

SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uhm what is all this gibberish? This shouldn't be in the repository

Comment thread ractor/Cargo.toml
cluster = []
monitors = []
message_span_propogation = []
derived-actor-from-cell = []
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't fully reviewed this PR, but if this is additive, we probably don't need a feature gate. People can choose to use it or not

#[cfg(feature = "cluster")]
supports_remoting: TActor::Msg::serializable(),
#[cfg(feature = "derived-actor-from-cell")]
derived_provider: Box::new(DerivedProviderType::<TActor>::new()),
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah ok this isn't additive, so the feature is necessary


/// Return a [DerivedActorRef<T>] from an [ActorCell].
///
/// This is usefull in scenario where the actual actor message type is unknown
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: usefull in scenario -> useful in scenarios

/// not provide this specific [DerivedActorRef] then this function will return
/// [None].
///
/// # Exemple
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Exemple -> Example

}
}

/// Type used as argument to [Message::proved_derived_actor_ref]
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo? proved_derived_actor_ref

state.send(message).await?;
Ok(())
}
fn provide_derived_actor_ref<'a>(
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why can't this be a trait defined on the message type, rather the actor type? An actor who supports derived messages, should support them in aggregate as the messages can be natively converted IMHO.

I.e. if message type A supports derived types B, and C, all actors of message A should support derived message types B and C along with this new from-cell functionality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants