Skip to content

Commit

Permalink
Feat - Added initial server config + readme update
Browse files Browse the repository at this point in the history
  • Loading branch information
GuicLuca committed Oct 26, 2023
1 parent fbe660c commit 48af159
Show file tree
Hide file tree
Showing 6 changed files with 305 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/BuildAndTestOnPush.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build, Test, and Package with Comment Coverage
name: Build, Test, and Package

on:
push:
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# RekT_Protocol

[![crates.io](https://img.shields.io/crates/v/rekt-protocol-common.svg)](https://crates.io/crates/rekt-protocol-common)
[![docs.rs](https://github.com/GuicLuca/RekT_Protocole/actions/workflows/BuildAndTestOnPush.yml/badge.svg)](https://github.com/GuicLuca/RekT_Protocole/actions/workflows/BuildAndTestOnPush.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![HitCount](https://hits.dwyl.com/Guicluca/RekT_Protocole.svg)](https://hits.dwyl.com/GuicLuca/Rekt_Protocole)

****

> **Author** : *Guichard Lucas* <lucasguichard127@gmail.com> [(Portfolio)](https://konekan.fr) <br>
> **Teacher** : *Plantevin Valère*<br>
> **Learning**: 3017 - Master degree in computer science, research profile<br>
Expand Down
7 changes: 7 additions & 0 deletions RektBroker/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,10 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde = { version = "1.0.189" , features = ["derive"] }
toml = "0.8.2"
log = "0.4.20"
pretty_env_logger = "0.5.0"
lazy_static = { version = "1.4.0", features = [] }
local-ip-address = "0.5.6"
quiche = "0.18.0"
16 changes: 16 additions & 0 deletions RektBroker/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[server]
port="3838"

[period]
heartbeat_period=2 #secondes
ping_period=10 #secondes

[debug]
debug_level="info" # trace, debug, info, warn, error
debug_datagram_handler = true
debug_ping_sender = true
debug_data_handler = true
debug_heartbeat_checker = true
debug_topic_handler = true
debug_client_manager = true
debug_object_handler = true
217 changes: 217 additions & 0 deletions RektBroker/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
// This document contain the config system. It read values from a toml file and
// then it return it as a rust structure.
// @author : GuicLuca (lucasguichard127@gmail.com)
// date : 14/03/2023

use std::fs;
use std::io::Error;
use serde::{Deserialize, Serialize};
use toml;


// Contain the Server table of the toml file
#[derive(Serialize, Deserialize, Debug)]
struct ConfigTomlServer {
port: Option<String>,
}

// Contain the Period table of the toml file
#[derive(Serialize, Deserialize, Debug)]
struct ConfigTomlPeriod {
heartbeat_period: Option<u16>,
ping_period: Option<u16>,
}

// Contain the Debug table of the toml file
#[derive(Serialize, Deserialize, Debug)]
struct ConfigTomlDebug {
debug_level: Option<String>,
debug_datagram_handler: Option<bool>,
debug_ping_sender: Option<bool>,
debug_data_handler: Option<bool>,
debug_heartbeat_checker: Option<bool>,
debug_topic_handler: Option<bool>,
debug_client_manager: Option<bool>,
debug_object_handler: Option<bool>,
}

// Used to load every table of the toml file
#[derive(Serialize, Deserialize, Debug)]
struct ConfigToml {
server: Option<ConfigTomlServer>,
debug: Option<ConfigTomlDebug>,
period: Option<ConfigTomlPeriod>,
}

// This is the final structure that contain every
// values of the toml file.
#[derive(Debug)]
pub struct Config {
pub port: u16,
pub heart_beat_period: u16,
pub ping_period: u16,
pub debug_level: String,
pub debug_datagram_handler: bool,
pub debug_ping_sender: bool,
pub debug_data_handler: bool,
pub debug_heartbeat_checker: bool,
pub debug_topic_handler: bool,
pub debug_client_manager: bool,
pub debug_object_handler: bool,
}

impl Config {
pub fn new() -> Self {
info!("Loading config.toml file...");
// 1 - List of path to config files
let config_filepath: [&str; 2] = [
"./config.toml",
"./src/config.toml",
];

// 2 - Loop through each config file to get the first valid one
let mut content: String = "".to_owned();

for filepath in config_filepath {
let result: Result<String, Error> = fs::read_to_string(filepath);

if result.is_ok() {
content = result.unwrap_or_else(|err|{
println!("Failed to unwrap content string. Error:\n{}", err);
"".to_owned() // return default value
});
break;
}
}

info!("Reading config.toml file...");

// 3 - Extract the content to a toml object
let config_toml: ConfigToml = match toml::from_str(&content) {
Ok(config) => config,
Err(e) => {
println!("Failed to create ConfigToml Object out of config file. Error: {:?}", e);
ConfigToml {
server: None,
period: None,
debug: None,
}
}
};

// 4 - Get every value into local variables
info!("Creating server config table...");

// 4.1 - Server variables
let port: u16 = match config_toml.server {
Some(server) => {
let port: u16 = match server.port.unwrap_or_else(|| {
println!("Missing field port in table server.");
"unknown".to_owned()
}).parse::<u16>() {
Ok(value) => {
value
}
Err(err) => {
println!("Failed to parse port into a u16. Error:\n{}", err);
3838 // return default value
}
};

port
}
None => {
println!("Missing table server.");
3838 // Default value if none found
}
};

// 4.2 - Period variables
info!("Creating period config table...");
let (heartbeat_period, ping_period): (u16, u16) = match config_toml.period {
Some(period) => {
let hb_period = period.heartbeat_period.unwrap_or_else(|| {
println!("Missing field heartbeat_period in table period.");
5 // Default value if none found
});
let ping_period = period.ping_period.unwrap_or_else(|| {
println!("Missing field ping_period in table period.");
5 // Default value if none found
});

(hb_period, ping_period)
}
None => {
println!("Missing table period.");
(5, 5) // Default value if none found
}
};

// 4.3 - Debug variables
info!("Creating debug config table...");
let (debug_level,
debug_datagram_handler,
debug_ping_sender,
debug_data_handler,
debug_heartbeat_checker,
debug_topic_handler,
debug_client_manager,
debug_object_handler,): (String, bool, bool, bool, bool, bool, bool, bool) = match config_toml.debug {
Some(debug) => {
let d_level: String = debug.debug_level.unwrap_or_else(|| {
println!("Missing field debug_level in table debug.");
"trace".to_string() // Default value if none found
});
let d_ping = debug.debug_ping_sender.unwrap_or_else(|| {
println!("Missing field debug_ping_sender in table debug.");
true // Default value if none found
});
let d_datagram = debug.debug_datagram_handler.unwrap_or_else(|| {
println!("Missing field debug_datagram_handler in table debug.");
true // Default value if none found
});
let d_data = debug.debug_data_handler.unwrap_or_else(|| {
println!("Missing field debug_data_handler in table debug.");
true // Default value if none found
});
let d_heart = debug.debug_heartbeat_checker.unwrap_or_else(|| {
println!("Missing field debug_heartbeat_checker in table debug.");
true // Default value if none found
});
let d_topic = debug.debug_topic_handler.unwrap_or_else(|| {
println!("Missing field debug_topic_handler in table debug.");
true // Default value if none found
});
let d_manager = debug.debug_client_manager.unwrap_or_else(|| {
println!("Missing field debug_client_manager in table debug.");
true // Default value if none found
});
let d_object = debug.debug_object_handler.unwrap_or_else(|| {
println!("Missing field debug_object_handler in table debug.");
true // Default value if none found
});

(d_level, d_datagram, d_ping, d_data, d_heart, d_topic, d_manager, d_object)
}
None => {
println!("Missing table debug.");
("trace".to_string(), true, true, true, true, true, true, true) // Default value if none found
}
};


Config {
port,
heart_beat_period: heartbeat_period,
ping_period,
debug_level,
debug_datagram_handler,
debug_ping_sender,
debug_data_handler,
debug_heartbeat_checker,
debug_topic_handler,
debug_client_manager,
debug_object_handler
}
}
}
60 changes: 57 additions & 3 deletions RektBroker/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,61 @@
// Todo : remove this unused code ignore macro once the project will start
#![allow(unused)]
// This document contain the main task of the broker. The task datagram_handler
// must never be blocked by any method ! The whole project use tokio and work
// asynchronously to allow a maximum bandwidth computing. The goal of the broker is
// to handle 100Gb/s.
// For each features the memory management and the cpu usage should be in the middle of the reflexion.
//
// @author : GuicLuca (lucasguichard127@gmail.com)
// date : 21/10/2023\

extern crate pretty_env_logger;
#[macro_use] extern crate log;

use lazy_static::lazy_static;
use local_ip_address::local_ip;
use crate::config::Config;


mod config;


lazy_static! {
//static ref ISRUNNING: Arc<RwLock<bool>> = Arc::from(RwLock::from(false)); // Flag showing if the server is running or not
static ref CONFIG: Config = Config::new(); // Unique reference to the config object
/*
// List of client's :
static ref CLIENTS_SENDERS_REF: ClientsHashMap<ClientSender> = Arc::new(RwLock::new(HashMap::default())); // <Client ID, Sender> -> the sender is used to sent command through the mpsc channels
static ref CLIENTS_STRUCTS_REF: ClientsHashMap<Arc<Mutex<Client>>> = Arc::new(RwLock::new(HashMap::default())); // <Client ID, Struct> -> used only to keep struct alive
static ref CLIENTS_ADDRESSES_REF: ClientsHashMap<SocketAddr> = Arc::new(RwLock::new(HashMap::default())); // <Client ID, address> -> Used to send data
// List of time reference for ping requests
static ref PINGS_REF: PingsHashMap = Arc::new(Mutex::new(HashMap::default())); // <Ping ID, reference time in ms>
// List of topic subscribers
static ref TOPICS_SUBSCRIBERS_REF: TopicsHashMap<HashSet<ClientId>> = Arc::new(RwLock::new(HashMap::default())); // <Topic ID, [Clients ID]>
// List of Objects (group of topics)
static ref OBJECTS_TOPICS_REF: ObjectHashMap<HashSet<TopicId>> = Arc::new(RwLock::new(HashMap::default())); // <ObjectId, [TopicId]>
static ref OBJECT_SUBSCRIBERS_REF: ObjectHashMap<HashSet<ClientId>> = Arc::new(RwLock::new(HashMap::default())); // <ObjectId, [ClientId]>*/
}

fn main(){
println!("Hello, world!");
// Set the rust log environment variable and then init the rust logger
std::env::set_var("RUST_LOG", &CONFIG.debug_level);
pretty_env_logger::init();

info!("Static variables and configuration initialized ...");
info!("Log level set to {} ...", &CONFIG.debug_level);
info!("- Check config.toml file to change the config. -");

// Fetch the local ip address and config port to start the server
match local_ip() {
Ok(ip) => info!("Server starting on {}:{} ...", ip, &CONFIG.port),
Err(err) => {
error!("Failed to get local IP:\n{}", err);
error!("\n\nServer stopping!");
return; // can't start the server if the local ip can't be reach
}
};


}

0 comments on commit 48af159

Please sign in to comment.