Skip to content

Commit

Permalink
write minimal-update-client-server example
Browse files Browse the repository at this point in the history
  • Loading branch information
N8BWert committed Sep 6, 2024
1 parent dac141d commit d7b19b1
Show file tree
Hide file tree
Showing 14 changed files with 240 additions and 296 deletions.
9 changes: 8 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ members = [
"ncomm-clients-and-servers",
"ncomm-update-clients-and-servers",
"examples/minimal-client-server",
"examples/minimal-update-server-client",
"examples/minimal-update-client-server",
"examples/minimal-publisher-subscriber",
]

Expand All @@ -19,6 +19,7 @@ default-members = [
"ncomm-clients-and-servers",
"ncomm-update-clients-and-servers",
]
resolver = "2"

[workspace.package]
name = "ncomm"
Expand Down
2 changes: 1 addition & 1 deletion examples/minimal-client-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ ncomm-executors = { workspace = true }
ncomm-clients-and-servers = { workspace = true }
crossbeam = { workspace = true }
ctrlc = { workspace = true }
rand = { workspace = true }
rand = { workspace = true }
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "minimal-update-server-client"
description = "Minimal Update Server and Client example based on the [Ros 2 Tutorial](https://docs.ros.org/en/foxy/Tutorials/Intermediate/Writing-an-Action-Server-Client/Cpp.html)"
name = "minimal-update-client-server"
description = "Minimal Update Client and Server example based on the [Ros 2 Tutorial](https://docs.ros.org/en/foxy/Tutorials/Intermediate/Writing-an-Action-Server-Client/Cpp.html)"
version.workspace = true
edition.workspace = true
license.workspace = true
Expand All @@ -12,3 +12,8 @@ authors.workspace = true
categories.workspace = true

[dependencies]
ncomm-core = { workspace = true }
ncomm-executors = { workspace = true }
ncomm-update-clients-and-servers = { workspace = true }
crossbeam = { workspace = true }
ctrlc = { workspace = true }
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//!
//! A Simple Update Client Example that sends a request for the nth term in the
//! fibonacci series.
//!

use super::{FibonacciRequest, FibonacciUpdate, FibonacciResponse};

use ncomm_core::{Node, UpdateClient};
use ncomm_update_clients_and_servers::local::LocalUpdateClient;

/// A simple update client node that sends a request for the nth term in the
/// fibonacci series, printing the numbers in the series before receiving the nth
/// number in the series
pub struct FibonacciUpdateClient {
update_client: LocalUpdateClient<FibonacciRequest, FibonacciUpdate, FibonacciResponse>,
}

impl FibonacciUpdateClient {
/// Create a new Fibonacci Update Client
pub fn new(update_client: LocalUpdateClient<FibonacciRequest, FibonacciUpdate, FibonacciResponse>) -> Self {
Self {
update_client,
}
}

/// Print the update messages received
pub fn handle_updates(&mut self) {
let updates = self.update_client.poll_for_updates();
for update in updates.iter() {
if let Ok((_request, update)) = update {
println!("Last Num: {} --- Current Num: {}", update.last_num, update.current_num);
}
}
}

/// Print the response message received and send a new request for the 10th order of
/// a fibonacci sequence
pub fn handle_response(&mut self) {
let responses = self.update_client.poll_for_responses();
for response in responses.iter() {
if let Ok((request, response)) = response {
println!("f(10) = {}", response.num);
self.update_client.send_request(request.clone()).unwrap();
}
}
}
}

impl Node for FibonacciUpdateClient {
fn get_update_delay_us(&self) -> u128 {
100_000
}

fn start(&mut self) {
self.update_client.send_request(FibonacciRequest { order: 10 }).unwrap();
}

fn update(&mut self) {
self.handle_updates();
self.handle_response();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
//!
//! An update server example that calculates the nth term in the
//! fibonacci sequence, updating a client with each sequence of terms
//! into the series
//!

use super::{FibonacciRequest, FibonacciUpdate, FibonacciResponse};

use ncomm_core::{Node, UpdateServer};
use ncomm_update_clients_and_servers::local::{LocalUpdateClient, LocalUpdateServer};

/// An update server node that calculates the nth term in the fibonacci
/// sequence
///
/// Note: for this example, the update server only expects a single client but
/// it would be trivial to make this update server capable of handling multiple
/// clients.
pub struct FibonacciUpdateServer {
last_num: u128,
current_num: u128,
order: u128,
current_order: u128,
current_request: Option<(String, FibonacciRequest)>,
update_server: LocalUpdateServer<FibonacciRequest, FibonacciUpdate, FibonacciResponse, String>,
}

impl FibonacciUpdateServer {
/// Create a new fibonacci update server
pub fn new() -> Self {
Self {
last_num: 1,
current_num: 1,
order: 1,
current_order: 1,
current_request: None,
update_server: LocalUpdateServer::new(),
}
}

/// Create a client for the fibonacci update server node
pub fn create_client(&mut self, client_name: String) -> LocalUpdateClient<FibonacciRequest, FibonacciUpdate, FibonacciResponse> {
self.update_server.create_update_client(client_name)
}

/// Check for requests
fn handle_requests(&mut self) {
if let Some(Ok((client, request))) = self.update_server.poll_for_requests().last() {
self.current_request = Some((client.clone(), request.clone()));
self.order = request.order;
self.last_num = 1;
self.current_num = 1;
self.current_order = 1;
}
}

/// Send Updates for the current client
fn send_updates(&mut self) {
if let Some((client_id, request)) = self.current_request.as_ref() {
let next_num = self.last_num + self.current_num;
self.last_num = self.current_num;
self.current_num = next_num;
self.update_server.send_update(
client_id.clone(),
&request,
FibonacciUpdate { last_num: self.last_num, current_num: self.current_num }
).unwrap();
self.current_order += 1;
}
}

/// Send final response for the current client
fn send_response(&mut self) {
if self.current_request.is_some() && self.current_order == self.order {
let (client_id, request) = self.current_request.take().unwrap();
self.update_server.send_response(
client_id,
request,
FibonacciResponse { num: self.current_num }
).unwrap();
}
}
}

impl Node for FibonacciUpdateServer {
fn get_update_delay_us(&self) -> u128 {
100_000
}

fn update(&mut self) {
self.handle_requests();
self.send_updates();
self.send_response();
}
}
66 changes: 66 additions & 0 deletions examples/minimal-update-client-server/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//!
//! Example for a minimal update client and server where
//! the server requests a a fibonacci value of some order and
//! the server responds with updates containing the last and current
//! value in a fibonacci series before it finds the fibonacci value of
//! given degree which is returned as a response
//!

#![deny(missing_docs)]

use ncomm_core::Executor;
use ncomm_executors::SimpleExecutor;

use crossbeam::channel::unbounded;

pub mod fibonacci_update_client;
use fibonacci_update_client::FibonacciUpdateClient;

pub mod fibonacci_update_server;
use fibonacci_update_server::FibonacciUpdateServer;

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
/// A request asking for a the nth order of the fibonacci sequence.
pub struct FibonacciRequest {
/// The nth term of the fibonacci sequence to compute
pub order: u128,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
/// An update containing the current last number and the current number
/// the update server has currently computed.
pub struct FibonacciUpdate {
/// The order n-1 term of the fibonacci sequence
pub last_num: u128,
/// The order n term of the fibonacci sequence
pub current_num: u128,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
/// A response containing the number at a given order of the fibonacci
/// sequence.
pub struct FibonacciResponse {
/// The order n term of the fibonacci sequence
pub num: u128,
}

fn main() {
let mut update_server_node = FibonacciUpdateServer::new();
let update_client_node = FibonacciUpdateClient::new(
update_server_node.create_client(String::from("Fibonacci Update Client"))
);

let (tx, rx) = unbounded();
ctrlc::set_handler(move || tx.send(true).expect("Unable to send data"))
.expect("Error setting Ctrl-C handler");

let mut executor = SimpleExecutor::new_with(
rx,
vec![
Box::new(update_client_node),
Box::new(update_server_node),
]
);

executor.update_loop();
}
3 changes: 0 additions & 3 deletions examples/minimal-update-server-client/src/main.rs

This file was deleted.

1 change: 0 additions & 1 deletion examples/minimal_update_service_client/.gitignore

This file was deleted.

Loading

0 comments on commit d7b19b1

Please sign in to comment.