Skip to content

Commit

Permalink
Merge pull request #18 from lsd-ucsc/call-hlist-location-set
Browse files Browse the repository at this point in the history
  • Loading branch information
shumbo authored Oct 3, 2023
2 parents e499079 + 0de1a30 commit 8f8f81a
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 45 deletions.
62 changes: 35 additions & 27 deletions chorus_lib/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ where

/// heterogeneous list
#[doc(hidden)]
pub trait HList {
pub trait LocationSet {
/// returns
fn to_string_list() -> Vec<&'static str>;
}
Expand All @@ -119,15 +119,15 @@ pub struct HNil;
#[doc(hidden)]
pub struct HCons<Head, Tail>(Head, Tail);

impl HList for HNil {
impl LocationSet for HNil {
fn to_string_list() -> Vec<&'static str> {
Vec::new()
}
}
impl<Head, Tail> HList for HCons<Head, Tail>
impl<Head, Tail> LocationSet for HCons<Head, Tail>
where
Head: ChoreographyLocation,
Tail: HList,
Tail: LocationSet,
{
fn to_string_list() -> Vec<&'static str> {
let mut v = Tail::to_string_list();
Expand Down Expand Up @@ -180,12 +180,12 @@ pub struct There<Index>(Index);
/// If a location `L1` is in `L`, then there exists a type `Index` such that `L1` implements `Member<L, Index>`.
pub trait Member<L, Index> {
/// A location set that is the remainder of `L` after removing the member.
type Remainder: HList;
type Remainder: LocationSet;
}

impl<Head, Tail> Member<HCons<Head, Tail>, Here> for Head
where
Tail: HList,
Tail: LocationSet,
{
type Remainder = Tail;
}
Expand All @@ -204,13 +204,14 @@ where
///
/// It takes two type parameters `L` and `Index`. `L` is a location set and `Index` is some type that is inferred by the compiler.
/// If a location set `M` is a subset of `L`, then there exists a type `Index` such that `M` implements `Subset<L, Index>`.
pub trait Subset<L: HList, Index> {}
pub trait Subset<L: LocationSet, Index> {}

// Base case: HNil is a subset of any set
impl<L: HList> Subset<L, Here> for HNil {}
impl<L: LocationSet> Subset<L, Here> for HNil {}

// Recursive case
impl<L: HList, Head, Tail: HList, IHead, ITail> Subset<L, HCons<IHead, ITail>> for HCons<Head, Tail>
impl<L: LocationSet, Head, Tail: LocationSet, IHead, ITail> Subset<L, HCons<IHead, ITail>>
for HCons<Head, Tail>
where
Head: Member<L, IHead>,
Tail: Subset<L, ITail>,
Expand All @@ -233,7 +234,7 @@ impl<L1: ChoreographyLocation> Unwrapper<L1> {
///
/// The trait provides methods to work with located values. An implementation of the trait is "injected" into
/// a choreography at runtime and provides the actual implementation of the operators.
pub trait ChoreoOp<L: HList> {
pub trait ChoreoOp<L: LocationSet> {
/// Performs a computation at the specified location.
///
/// `locally` performs a computation at a location, which are specified by `location` and `computation`, respectively.
Expand Down Expand Up @@ -278,10 +279,10 @@ pub trait ChoreoOp<L: HList> {
/// Calls a choreography.
fn call<R, M, Index, C: Choreography<R, L = M>>(&self, choreo: C) -> R
where
M: HList + Subset<L, Index>;
M: LocationSet + Subset<L, Index>;

/// Calls a choreography on a subset of locations.
fn colocally<R: Superposition, S: HList, C: Choreography<R, L = S>, Index>(
fn colocally<R: Superposition, S: LocationSet, C: Choreography<R, L = S>, Index>(
&self,
choreo: C,
) -> R
Expand All @@ -298,7 +299,7 @@ pub trait ChoreoOp<L: HList> {
/// The trait provides a method `run` that takes an implementation of `ChoreoOp` and returns a value of type `R`.
pub trait Choreography<R = ()> {
/// Locations
type L: HList;
type L: LocationSet;
/// A method that executes a choreography.
///
/// The method takes an implementation of `ChoreoOp`. Inside the method, you can use the operators provided by `ChoreoOp` to define a choreography.
Expand All @@ -314,7 +315,7 @@ pub trait Choreography<R = ()> {
/// The type parameter `L` is the location set that the transport is operating on.
///
/// The type parameter `TargetLocation` is the target `ChoreographyLocation`.
pub trait Transport<L: HList, TargetLocation: ChoreographyLocation> {
pub trait Transport<L: LocationSet, TargetLocation: ChoreographyLocation> {
/// Returns a list of locations.
fn locations(&self) -> Vec<String>;
/// Sends a message from `from` to `to`.
Expand All @@ -324,7 +325,7 @@ pub trait Transport<L: HList, TargetLocation: ChoreographyLocation> {
}

/// Provides a method to perform end-point projection.
pub struct Projector<LS: HList, L1: ChoreographyLocation, T: Transport<LS, L1>, Index>
pub struct Projector<LS: LocationSet, L1: ChoreographyLocation, T: Transport<LS, L1>, Index>
where
L1: Member<LS, Index>,
{
Expand All @@ -334,7 +335,8 @@ where
index: PhantomData<Index>,
}

impl<LS: HList, L1: ChoreographyLocation, B: Transport<LS, L1>, Index> Projector<LS, L1, B, Index>
impl<LS: LocationSet, L1: ChoreographyLocation, B: Transport<LS, L1>, Index>
Projector<LS, L1, B, Index>
where
L1: Member<LS, Index>,
{
Expand Down Expand Up @@ -377,22 +379,28 @@ where
}

/// Performs end-point projection and runs a choreography.
pub fn epp_and_run<'a, V, L: HList, C: Choreography<V, L = L>, IndexSet>(
pub fn epp_and_run<'a, V, L: LocationSet, C: Choreography<V, L = L>, IndexSet>(
&'a self,
choreo: C,
) -> V
where
L: Subset<LS, IndexSet>,
{
struct EppOp<'a, L: HList, L1: ChoreographyLocation, LS: HList, B: Transport<LS, L1>> {
struct EppOp<
'a,
L: LocationSet,
L1: ChoreographyLocation,
LS: LocationSet,
B: Transport<LS, L1>,
> {
target: PhantomData<L1>,
transport: &'a B,
locations: Vec<String>,
marker: PhantomData<L>,
projector_location_set: PhantomData<LS>,
}
impl<'a, L: HList, T: ChoreographyLocation, LS: HList, B: Transport<LS, T>> ChoreoOp<L>
for EppOp<'a, L, T, LS, B>
impl<'a, L: LocationSet, T: ChoreographyLocation, LS: LocationSet, B: Transport<LS, T>>
ChoreoOp<L> for EppOp<'a, L, T, LS, B>
{
fn locally<V, L1: ChoreographyLocation, Index>(
&self,
Expand Down Expand Up @@ -453,7 +461,7 @@ where

fn call<R, M, Index, C: Choreography<R, L = M>>(&self, choreo: C) -> R
where
M: HList + Subset<L, Index>,
M: LocationSet + Subset<L, Index>,
{
let op: EppOp<'a, M, T, LS, B> = EppOp {
target: PhantomData::<T>,
Expand All @@ -465,7 +473,7 @@ where
choreo.run(&op)
}

fn colocally<R: Superposition, S: HList, C: Choreography<R, L = S>, Index>(
fn colocally<R: Superposition, S: LocationSet, C: Choreography<R, L = S>, Index>(
&self,
choreo: C,
) -> R {
Expand Down Expand Up @@ -499,11 +507,11 @@ where
}

/// Provides a method to run a choreography without end-point projection.
pub struct Runner<L: HList> {
pub struct Runner<L: LocationSet> {
marker: PhantomData<L>,
}

impl<L: HList> Runner<L> {
impl<L: LocationSet> Runner<L> {
/// Constructs a runner.
pub fn new() -> Self {
Runner {
Expand All @@ -528,7 +536,7 @@ impl<L: HList> Runner<L> {
/// Runs a choreography directly
pub fn run<'a, V, C: Choreography<V, L = L>>(&'a self, choreo: C) -> V {
struct RunOp<L>(PhantomData<L>);
impl<L: HList> ChoreoOp<L> for RunOp<L> {
impl<L: LocationSet> ChoreoOp<L> for RunOp<L> {
fn locally<V, L1: ChoreographyLocation, Index>(
&self,
_location: L1,
Expand Down Expand Up @@ -569,13 +577,13 @@ impl<L: HList> Runner<L> {

fn call<R, M, Index, C: Choreography<R, L = M>>(&self, choreo: C) -> R
where
M: HList + Subset<L, Index>,
M: LocationSet + Subset<L, Index>,
{
let op: RunOp<M> = RunOp(PhantomData);
choreo.run(&op)
}

fn colocally<R: Superposition, S: HList, C: Choreography<R, L = S>, Index>(
fn colocally<R: Superposition, S: LocationSet, C: Choreography<R, L = S>, Index>(
&self,
choreo: C,
) -> R {
Expand Down
8 changes: 4 additions & 4 deletions chorus_lib/src/transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
pub mod http;
pub mod local;

use crate::core::{ChoreographyLocation, HCons, HList, LocationSet};
use crate::core::{ChoreographyLocation, HCons, LocationSet};
use std::collections::HashMap;
use std::marker::PhantomData;

/// A generic struct for configuration of `Transport`.
#[derive(Clone)]
pub struct TransportConfig<Target: ChoreographyLocation, TargetInfo, L: HList, Info> {
pub struct TransportConfig<Target: ChoreographyLocation, TargetInfo, L: LocationSet, Info> {
/// The information about locations
pub info: HashMap<String, Info>,
/// The information about the target choreography
Expand Down Expand Up @@ -38,7 +38,7 @@ pub struct TransportConfig<Target: ChoreographyLocation, TargetInfo, L: HList, I
/// .with(Bob, "value_for_bob".to_string())
/// .build();
/// ```
pub struct TransportConfigBuilder<Target: ChoreographyLocation, TargetInfo, L: HList, Info> {
pub struct TransportConfigBuilder<Target: ChoreographyLocation, TargetInfo, L: LocationSet, Info> {
target: (Target, TargetInfo),
location_set: PhantomData<L>,
info: HashMap<String, Info>,
Expand All @@ -57,7 +57,7 @@ impl<Target: ChoreographyLocation, TargetInfo, Info>
}
}

impl<Target: ChoreographyLocation, TargetInfo, L: HList, Info>
impl<Target: ChoreographyLocation, TargetInfo, L: LocationSet, Info>
TransportConfigBuilder<Target, TargetInfo, L, Info>
{
/// Adds information about a new `ChoreographyLocation`.
Expand Down
10 changes: 5 additions & 5 deletions chorus_lib/src/transport/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use tiny_http::Server;
use ureq::{Agent, AgentBuilder};

use crate::{
core::{ChoreographyLocation, HList, Member, Portable, Transport},
core::{ChoreographyLocation, LocationSet, Member, Portable, Transport},
transport::{TransportConfig, TransportConfigBuilder},
utils::queue::BlockingQueue,
};
Expand Down Expand Up @@ -48,7 +48,7 @@ pub type HttpTransportConfigBuilder<Target, L> =
const HEADER_SRC: &str = "X-CHORUS-SOURCE";

/// The HTTP transport.
pub struct HttpTransport<L: HList, TLocation> {
pub struct HttpTransport<L: LocationSet, TLocation> {
config: HashMap<String, (String, u16)>,
agent: Agent,
server: Arc<Server>,
Expand All @@ -58,7 +58,7 @@ pub struct HttpTransport<L: HList, TLocation> {
target_location: PhantomData<TLocation>,
}

impl<L: HList, TLocation: ChoreographyLocation> HttpTransport<L, TLocation> {
impl<L: LocationSet, TLocation: ChoreographyLocation> HttpTransport<L, TLocation> {
/// Creates a new `HttpTransport` instance from the configuration.
pub fn new<Index>(http_config: HttpTransportConfig<L, TLocation>) -> Self
where
Expand Down Expand Up @@ -119,14 +119,14 @@ impl<L: HList, TLocation: ChoreographyLocation> HttpTransport<L, TLocation> {
}
}

impl<L: HList, TLocation> Drop for HttpTransport<L, TLocation> {
impl<L: LocationSet, TLocation> Drop for HttpTransport<L, TLocation> {
fn drop(&mut self) {
self.server.unblock();
self.join_handle.take().map(thread::JoinHandle::join);
}
}

impl<L: HList, TLocation: ChoreographyLocation> Transport<L, TLocation>
impl<L: LocationSet, TLocation: ChoreographyLocation> Transport<L, TLocation>
for HttpTransport<L, TLocation>
{
fn locations(&self) -> Vec<String> {
Expand Down
18 changes: 9 additions & 9 deletions chorus_lib/src/transport/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@ use serde_json;

use std::marker::PhantomData;

use crate::core::{ChoreographyLocation, HCons, HList, LocationSet, Portable, Transport};
use crate::core::{ChoreographyLocation, HCons, LocationSet, Portable, Transport};
use crate::utils::queue::BlockingQueue;

type QueueMap = HashMap<String, HashMap<String, BlockingQueue<String>>>;

/// A Transport channel used between multiple `Transport`s.
pub struct LocalTransportChannel<L: HList> {
pub struct LocalTransportChannel<L: LocationSet> {
/// The location set where the channel is defined on.
location_set: std::marker::PhantomData<L>,
queue_map: Arc<QueueMap>,
}

impl<L: HList> Clone for LocalTransportChannel<L> {
impl<L: LocationSet> Clone for LocalTransportChannel<L> {
fn clone(&self) -> Self {
LocalTransportChannel {
location_set: PhantomData,
Expand All @@ -28,7 +28,7 @@ impl<L: HList> Clone for LocalTransportChannel<L> {
}
}

impl<L: HList> LocalTransportChannel<L> {
impl<L: LocationSet> LocalTransportChannel<L> {
/// Creates a new `LocalTransportChannel` instance.
///
/// You must specify the location set of the channel. The channel can only be used by locations in the set.
Expand Down Expand Up @@ -87,7 +87,7 @@ impl<L: HList> LocalTransportChannel<L> {
/// .with(Bob)
/// .build();
/// ```
pub struct LocalTransportChannelBuilder<L: HList> {
pub struct LocalTransportChannelBuilder<L: LocationSet> {
location_set: PhantomData<L>,
}

Expand All @@ -100,7 +100,7 @@ impl LocalTransportChannelBuilder<LocationSet!()> {
}
}

impl<L: HList> LocalTransportChannelBuilder<L> {
impl<L: LocationSet> LocalTransportChannelBuilder<L> {
/// Adds a new location to the set of locations in the `LocalTransportChannel`.
pub fn with<NewLocation: ChoreographyLocation>(
&self,
Expand All @@ -123,14 +123,14 @@ impl<L: HList> LocalTransportChannelBuilder<L> {
/// This transport uses a blocking queue to allow for communication between threads. Each location must be executed in its thread.
///
/// All locations must share the same `LocalTransportChannel` instance. `LocalTransportChannel` implements `Clone` so that it can be shared across threads.
pub struct LocalTransport<L: HList, TargetLocation> {
pub struct LocalTransport<L: LocationSet, TargetLocation> {
internal_locations: Vec<String>,
location_set: PhantomData<L>,
local_channel: LocalTransportChannel<L>,
target_location: PhantomData<TargetLocation>,
}

impl<L: HList, TargetLocation> LocalTransport<L, TargetLocation> {
impl<L: LocationSet, TargetLocation> LocalTransport<L, TargetLocation> {
/// Creates a new `LocalTransport` instance from a Target `ChoreographyLocation` and a `LocalTransportChannel`.
pub fn new(target: TargetLocation, local_channel: LocalTransportChannel<L>) -> Self {
_ = target;
Expand All @@ -151,7 +151,7 @@ impl<L: HList, TargetLocation> LocalTransport<L, TargetLocation> {
}
}

impl<L: HList, TargetLocation: ChoreographyLocation> Transport<L, TargetLocation>
impl<L: LocationSet, TargetLocation: ChoreographyLocation> Transport<L, TargetLocation>
for LocalTransport<L, TargetLocation>
{
fn locations(&self) -> Vec<String> {
Expand Down

0 comments on commit 8f8f81a

Please sign in to comment.