-
Notifications
You must be signed in to change notification settings - Fork 53
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
Modify Actor trait to take self
instead of &mut self
#2329
Modify Actor trait to take self
instead of &mut self
#2329
Conversation
Codecov Report
Additional details and impacted files
|
dfe7312
to
20cf36e
Compare
Robot Results
|
Nice, to see this move. I can only encourage you to move this forward.
I confirm that we only want to run actors once.
Running an actor as |
fn split(&mut self) -> (FromPeers<'_>, ToPeers<'_>) { | ||
fn split(self) -> (FromPeers, ToPeers) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both fn slip
and struct MqttMessageBox
can be deprecated as built & split only here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite understand what you mean here. I introduced split
as a mechanism to enable concurrent processing of incoming and outgoing messages, without the need for other actors to know/care about this detail (so outside there is still a single message box for a single actor). MqttActor
could potentially be split into two actors to deal with this, but that feels like it's just going to increase complexity in all the MQTT interactions for other actors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant that MqttActor
doesn't need to define a message box as a single object. In fact no actor has to. The abstraction with other actors is implemented by the builder with appropriate ServiceProvider
/ MessageSource
implementation.
The following is working fine:
pub struct MqttActor {
mqtt_config: mqtt_channel::Config,
from_peers: FromPeers,
to_peers: ToPeers,
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pushed a fixup commit: cc067c1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved. This really clarify the intent of Actor::run()
.
Signed-off-by: James Rhodes <jarhodes314@gmail.com>
cc067c1
to
f0f7f37
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved. Surprised to see that even the changes required in the runtime
module were so minimal.
@@ -25,7 +25,24 @@ pub trait Actor: 'static + Send + Sync { | |||
/// Processing input messages, | |||
/// updating internal state, | |||
/// and sending messages to peers. | |||
async fn run(&mut self) -> Result<(), RuntimeError>; | |||
async fn run(self) -> Result<(), RuntimeError>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering why you didn't go with the simpler fix of self: Box<Self>
(suggested in that same forum discussion) here instead. I'm assuming you did that to make the run
method implemented by the actors look more natural and hide the complexity of Box<Self>
with that blanket impl of ActorBoxed
below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The existing API works well for our use case, and I really don't like tests polluted with boxing values simply because the actual code uses dynamic dispatch somewhere.
Box<Self>
is very much an implementation detail here, and I want to be clear about that, particularly given the main change that's actually being made here is to the communication of what run
means and what assumptions can be made when implementing it, which up until now have been implicit. Receiving Box<Self>
doesn't tell me anything useful as an implementor of the trait, and because it's pretty uncommon thing, it's likely to cause some confusion among people.
Proposed changes
In #2327, some changes have been made that assume we only run
MqttActor::run
once. As far as I can tell, we only ever want to run actors once, but some complexity around calling consuming methods (i.e. those which take an ownedself
argument) fromBox<dyn Actor>
prevented us from doing that. I've managed to work around this and modifiedActor::run
to receiveself
instead of&mut self
.Types of changes
Paste Link to the issue
Checklist
cargo fmt
as mentioned in CODING_GUIDELINEScargo clippy
as mentioned in CODING_GUIDELINESFurther comments