Skip to content

Commit

Permalink
Merge branch 'main' into load-balancer
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnMurray committed May 19, 2023
2 parents 14fa7f3 + 4fd3673 commit 15fbef6
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 35 deletions.
5 changes: 4 additions & 1 deletion src/actor/address.proto
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ enum Scheme {
REMOTE = 1;
}

// ActorAddress is the serializable representation of an actor address. It can be used
// to send an address to another actor for the purpose of discovery and message routing.
message ActorAddress {

Scheme scheme = 1;
string path = 2;
}

// AddressList is a simple container for holding a list of ActorAddress messages.
// This allows for multiple addresses to be sent as a single message from/to an actor.
message AddressList {
repeated ActorAddress addresses = 1;
}
32 changes: 11 additions & 21 deletions src/actor/address.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::actor::proto::Scheme;
use crate::actor::{Letter, Mailbox};
use crate::message::Message;
use log::trace;
Expand Down Expand Up @@ -45,7 +46,7 @@ impl ActorAddress {

pub(crate) fn new_root(name: &str) -> Self {
Self {
uri: Uri::new(UriScheme::Local, &[name]),
uri: Uri::new(Scheme::Local, &[name]),
mailbox: RefCell::new(None),
}
}
Expand Down Expand Up @@ -80,18 +81,6 @@ impl ActorAddress {
}
}

/// `UriScheme` is the transport mechanism for messages sent between actor systems. Messages
/// that stay within the current actor system will all have a `Local` scheme.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub(crate) enum UriScheme {
/// `Local` is the default scheme for messages that stay within the current actor system.
Local,

/// `Remote` is currently a placeholder value since remote is not currently implemented.
#[allow(dead_code)]
Remote,
}

/// `Uri` is a URI-like type that identifies an actor system and an actor within that system.
/// The hierarchical nature, or tree-like, organization of actors is also present in URIs, with
/// children and parents readily identifiable by path. Take for example the following hierarchy
Expand All @@ -112,12 +101,12 @@ pub(crate) enum UriScheme {
/// ```
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Uri {
pub(crate) scheme: UriScheme,
pub(crate) scheme: Scheme,
pub(crate) path_segments: Vec<String>,
}

impl Uri {
fn new(scheme: UriScheme, path_segments: &[&str]) -> Self {
fn new(scheme: Scheme, path_segments: &[&str]) -> Self {
if path_segments.is_empty() {
panic!("Uri must have at least one path segment");
}
Expand Down Expand Up @@ -161,6 +150,7 @@ impl Uri {
maybe_parent.is_child(self)
}

/// Return the path component of the [`Uri`] as a string.
pub(crate) fn path(&self) -> String {
self.path_segments.join("/")
}
Expand All @@ -169,8 +159,8 @@ impl Uri {
impl Display for Uri {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self.scheme {
UriScheme::Local => write!(f, "local://")?,
UriScheme::Remote => write!(f, "remote://")?,
Scheme::Local => write!(f, "local://")?,
Scheme::Remote => write!(f, "remote://")?,
}
write!(f, "{}", self.path_segments.join("/"))
}
Expand All @@ -184,13 +174,13 @@ mod tests {
#[should_panic]
fn test_construction() {
// Test that an empty path is not allowed
Uri::new(UriScheme::Local, &[]);
Uri::new(Scheme::Local, &[]);
}

#[test]
fn test_child_construction() {
// Create a child from a root path
let root = Uri::new(UriScheme::Local, &["root"]);
let root = Uri::new(Scheme::Local, &["root"]);
let child = root.new_child("child");

// Test the relationships between the two
Expand All @@ -211,7 +201,7 @@ mod tests {

#[test]
fn test_self_reference() {
let path = Uri::new(UriScheme::Local, &["root", "some", "path"]);
let path = Uri::new(Scheme::Local, &["root", "some", "path"]);
assert_eq!(path.is_child(&path), false);
assert_eq!(path.is_parent(&path), false);
}
Expand Down Expand Up @@ -262,7 +252,7 @@ mod tests {
),
];
for (path_segments, expected) in test_cases {
let uri = Uri::new(UriScheme::Local, &path_segments);
let uri = Uri::new(Scheme::Local, &path_segments);
assert_eq!(uri.to_string(), expected);
}
}
Expand Down
23 changes: 10 additions & 13 deletions src/actor/proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
//! [`ToMessage`](crate::message::ToMessage) implementations for these types.

use crate::actor;
use crate::actor::UriScheme;
use crate::message::common_types::impl_busan_message;
use crate::message::{Message, ToMessage};
use std::cell::RefCell;
Expand All @@ -20,31 +19,29 @@ impl ToMessage<ActorAddress> for &actor::ActorAddress {
fn to_message(self) -> ActorAddress {
ActorAddress {
scheme: match self.uri.scheme {
UriScheme::Local => Scheme::Local as i32,
UriScheme::Remote => Scheme::Remote as i32,
Scheme::Local => Scheme::Local as i32,
Scheme::Remote => Scheme::Remote as i32,
},
path: self.uri.path(),
}
}
}

impl From<ActorAddress> for actor::ActorAddress {
fn from(address: ActorAddress) -> Self {
let scheme = match address.scheme {
s if s == Scheme::Local as i32 => UriScheme::Local,
s if s == Scheme::Remote as i32 => UriScheme::Remote,
// TODO: Should this be implemented as a TryFrom instead?
_ => panic!("Invalid scheme"),
};
actor::ActorAddress {
impl TryFrom<ActorAddress> for actor::ActorAddress {
type Error = String;

fn try_from(address: ActorAddress) -> Result<Self, Self::Error> {
let scheme = Scheme::from_i32(address.scheme)
.ok_or(format!("Invalid scheme: {}", address.scheme))?;
Ok(actor::ActorAddress {
// TODO: This needs an internal constructor. Presumably there is at least
// one other place we're doing this same thing
uri: actor::Uri {
scheme,
path_segments: address.path.split('/').map(|s| s.to_string()).collect(),
},
mailbox: RefCell::new(None),
}
})
}
}

Expand Down

0 comments on commit 15fbef6

Please sign in to comment.