Runner

Runner is a struct that can be used to run a Choreography without doing end-point projection. It gives semantics to the Choreography and allows it to be run in a way that is similar to a function call.

To use Runner, construct an instance using the new constructor, and then call the run method with the Choreography.

#![allow(unused)]
fn main() {
extern crate chorus_lib;
use chorus_lib::core::{ChoreoOp, Choreography, ChoreographyLocation, Projector, Located, Superposition, Runner, LocationSet};
use chorus_lib::transport::local::{LocalTransport, LocalTransportChannelBuilder};
#[derive(ChoreographyLocation)]
struct Alice;
#[derive(ChoreographyLocation)]
struct Bob;
#[derive(ChoreographyLocation)]
struct Carol;
let transport_channel = LocalTransportChannelBuilder::new().with(Alice).with(Bob).with(Carol).build();
let alice_transport = LocalTransport::new(Alice, transport_channel.clone());
let bob_transport = LocalTransport::new(Bob, transport_channel.clone());
let carol_transport = LocalTransport::new(Carol, transport_channel.clone());
struct DemoChoreography;
impl Choreography for DemoChoreography {
    type L = LocationSet!();
    fn run(self, op: &impl ChoreoOp<Self::L>) {
    }
}
let runner = Runner::new();
runner.run(DemoChoreography);
}

As described in the Input and Output section, Runner can also pass values to the Choreography and receive values from it.

Because Runner executes the Choreography at all locations, all located inputs must be provided. Also, Runner can unwrap any located values returned by the Choreography.

#![allow(unused)]
fn main() {
extern crate chorus_lib;
use chorus_lib::core::{ChoreoOp, Choreography, ChoreographyLocation, Projector, Located, Superposition, Runner, LocationSet};
use chorus_lib::transport::local::{LocalTransport, LocalTransportChannelBuilder};
#[derive(ChoreographyLocation)]
struct Alice;
#[derive(ChoreographyLocation)]
struct Bob;
#[derive(ChoreographyLocation)]
struct Carol;
let transport_channel = LocalTransportChannelBuilder::new().with(Alice).with(Bob).with(Carol).build();
let alice_transport = LocalTransport::new(Alice, transport_channel.clone());
let bob_transport = LocalTransport::new(Bob, transport_channel.clone());
let carol_transport = LocalTransport::new(Carol, transport_channel.clone());
struct SumChoreography {
    x_at_alice: Located<u32, Alice>,
    y_at_bob: Located<u32, Bob>,
}
impl Choreography<Located<u32, Carol>> for SumChoreography {
    type L = LocationSet!(Alice, Bob, Carol);
    fn run(self, op: &impl ChoreoOp<Self::L>) -> Located<u32, Carol> {
        let x_at_carol = op.comm(Alice, Carol, &self.x_at_alice);
        let y_at_carol = op.comm(Bob, Carol, &self.y_at_bob);
        op.locally(Carol, |un| {
            let x = un.unwrap(&x_at_carol);
            let y = un.unwrap(&y_at_carol);
            x + y
        })
    }
}

let runner = Runner::new();
let x_at_alice = runner.local(1);
let y_at_bob = runner.local(2);
let sum_at_carol = runner.run(SumChoreography {
    x_at_alice,
    y_at_bob,
});
assert_eq!(runner.unwrap(sum_at_carol), 3);
}