Skip to content
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

Add Rust support example #27

Open
wants to merge 2 commits into
base: 2024
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 25 additions & 7 deletions week-01/anysystem-intro/ping-pong/tests/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use sugars::boxed;

use anysystem::python::PyProcessFactory;
use anysystem::test::TestResult;
use anysystem::{Message, System};
use anysystem::{Message, Process, System};

use crate::solution::{basic, retry, TestLanguage, LANGUAGE};

#[derive(Clone)]
pub struct TestConfig {
Expand All @@ -15,12 +17,28 @@ pub fn build_system(config: &TestConfig) -> System {
let mut sys = System::new(config.seed);
sys.add_node("server-node");
sys.add_node("client-node");
let server_f = PyProcessFactory::new(&config.impl_path, "PingServer");
let server = server_f.build(("server",), config.seed);
let client_f = PyProcessFactory::new(&config.impl_path, "PingClient");
let client = client_f.build(("client", "server"), config.seed);
sys.add_process("server", boxed!(server), "server-node");
sys.add_process("client", boxed!(client), "client-node");
let (server, client): (Box<dyn Process>, Box<dyn Process>) = match LANGUAGE {
TestLanguage::Python => {
let server_f = PyProcessFactory::new(&config.impl_path, "PingServer");
let server = server_f.build(("server",), config.seed);
let client_f = PyProcessFactory::new(&config.impl_path, "PingClient");
let client = client_f.build(("client", "server"), config.seed);
(boxed!(server), boxed!(client))
}
TestLanguage::Rust => match () {
() if config.impl_path.contains("basic") => (
boxed!(basic::Server::new()),
boxed!(basic::Client::new("server")),
),
() if config.impl_path.contains("retry") => (
boxed!(retry::Server::new()),
boxed!(retry::Client::new("server")),
),
() => unreachable!(),
},
};
sys.add_process("server", server, "server-node");
sys.add_process("client", client, "client-node");
sys
}

Expand Down
1 change: 1 addition & 0 deletions week-01/anysystem-intro/ping-pong/tests/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod common;
mod solution;
mod tests;
mod tests_mc;

Expand Down
61 changes: 61 additions & 0 deletions week-01/anysystem-intro/ping-pong/tests/src/solution/basic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use anysystem::{Context, Message, Process};

#[derive(Clone)]
pub struct Client {
server: String,
}

impl Client {
pub fn new(server: &str) -> Self {
Self {
server: server.to_string(),
}
}
}

impl Process for Client {
fn on_message(&mut self, msg: Message, _from: String, ctx: &mut Context) -> Result<(), String> {
if msg.tip == "PONG" {
ctx.send_local(msg);
}
Ok(())
}

fn on_local_message(&mut self, msg: Message, ctx: &mut Context) -> Result<(), String> {
if msg.tip == "PING" {
ctx.send(msg, self.server.clone());
}
Ok(())
}

fn on_timer(&mut self, _timer: String, _ctx: &mut Context) -> Result<(), String> {
Ok(())
}
}

#[derive(Clone)]
pub struct Server {}

impl Server {
pub fn new() -> Self {
Self {}
}
}

impl Process for Server {
fn on_message(&mut self, msg: Message, from: String, ctx: &mut Context) -> Result<(), String> {
if msg.tip == "PING" {
let resp = Message::new("PONG".to_string(), msg.data);
ctx.send(resp, from);
}
Ok(())
}

fn on_local_message(&mut self, _msg: Message, _ctx: &mut Context) -> Result<(), String> {
Ok(())
}

fn on_timer(&mut self, _timer: String, _ctx: &mut Context) -> Result<(), String> {
Ok(())
}
}
12 changes: 12 additions & 0 deletions week-01/anysystem-intro/ping-pong/tests/src/solution/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/// Language to use
/// Change to `Rust` to test rust implementation
pub const LANGUAGE: TestLanguage = TestLanguage::Python;

#[allow(dead_code)]
pub enum TestLanguage {
Python,
Rust,
}

pub mod basic;
pub mod retry;
83 changes: 83 additions & 0 deletions week-01/anysystem-intro/ping-pong/tests/src/solution/retry.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use std::rc::Rc;

use anysystem::{Context, Message, Process, ProcessState};

#[derive(Clone)]
pub struct Client {
server: String,
ping: Option<Message>,
}

impl Client {
pub fn new(server: &str) -> Self {
Self {
server: server.to_string(),
ping: None,
}
}
}

impl Process for Client {
fn on_message(&mut self, msg: Message, _from: String, ctx: &mut Context) -> Result<(), String> {
if msg.tip == "PONG" {
self.ping = None;
ctx.cancel_timer("check-pong");
ctx.send_local(msg);
}
Ok(())
}

fn on_local_message(&mut self, msg: Message, ctx: &mut Context) -> Result<(), String> {
if msg.tip == "PING" {
self.ping = Some(msg.clone());
ctx.send(msg, self.server.clone());
ctx.set_timer("check-pong", 3.);
}
Ok(())
}

fn on_timer(&mut self, timer: String, ctx: &mut Context) -> Result<(), String> {
if timer == "check-pong" && self.ping.is_some() {
ctx.send(self.ping.as_ref().unwrap().clone(), self.server.clone());
ctx.set_timer("check-pong", 3.);
}
Ok(())
}

fn state(&self) -> Result<std::rc::Rc<dyn ProcessState>, String> {
Ok(Rc::new(self.ping.clone()))
}

fn set_state(&mut self, state: std::rc::Rc<dyn ProcessState>) -> Result<(), String> {
self.ping
.clone_from(state.downcast_rc::<Option<Message>>().unwrap().as_ref());
Ok(())
}
}

#[derive(Clone)]
pub struct Server {}

impl Server {
pub fn new() -> Self {
Self {}
}
}

impl Process for Server {
fn on_message(&mut self, msg: Message, from: String, ctx: &mut Context) -> Result<(), String> {
if msg.tip == "PING" {
let resp = Message::new("PONG".to_string(), msg.data);
ctx.send(resp, from);
}
Ok(())
}

fn on_local_message(&mut self, _msg: Message, _ctx: &mut Context) -> Result<(), String> {
Ok(())
}

fn on_timer(&mut self, _timer: String, _ctx: &mut Context) -> Result<(), String> {
Ok(())
}
}