Skip to content
This repository was archived by the owner on Feb 28, 2026. It is now read-only.
Merged
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
26 changes: 13 additions & 13 deletions Cargo.lock

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

10 changes: 9 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
[package]
name = "Deston"
name = "deston"
version = "0.1.0"
edition = "2021"

[lib]
name = "deston"
path = "src/lib.rs"

[[bin]]
name = "deston"
path = "src/main.rs"

[dependencies]
hyper = { version = "1", features = ["full"] }
tokio = { version = "1", features = ["full"] }
Expand Down
35 changes: 31 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,49 @@ cargo run --release
```

### Configuration
Modify `config.toml` to add servers, specify load-balancing algorithms, etc.:
Modify `config.toml` to configure the load balancer settings:

```toml
[load_balancer]
address = "127.0.0.1"
port = 8080
algorithm = "RoundRobin"
algorithm = "round_robin" # Options: "round_robin", "weighted_round_robin", "ip_hashing"
layer = "L4" # Options: "L4" (TCP), "L7" (HTTP)

[[server]]
address = "http://127.0.0.1:3000"
address = "127.0.0.1"
port = 3000
max_connections = 1000
weight = 1

[[server]]
address = "http://127.0.0.1:3001"
address = "127.0.0.1"
port = 3001
max_connections = 1000
weight = 1
```

#### Configuration Options

- **layer**: Choose between Layer 4 (TCP) or Layer 7 (HTTP) load balancing
- `"L4"` (default): Transport layer (TCP) load balancing
- `"L7"`: Application layer (HTTP) load balancing
- Case-insensitive: accepts `"l4"`, `"L4"`, `"layer4"`, `"Layer_4"`, etc.

- **algorithm**: Load balancing algorithm
- `"round_robin"`: Distributes requests equally across servers
- `"weighted_round_robin"`: Distributes based on server weights
- `"ip_hashing"`: Routes requests from the same IP to the same server
- Case-insensitive

- **address** and **port**: The address where the load balancer listens

- **server**: Backend server configuration
- `address`: Server IP address
- `port`: Server port
- `max_connections`: Maximum concurrent connections
- `weight`: Server weight (used with weighted_round_robin)

---

## 📜 Code Snippets
Expand Down
2 changes: 1 addition & 1 deletion config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
address = "127.0.0.1"
port = 8080
algorithm = "round_robin"
layer = "L7"

[[server]]
address = "127.0.0.1"
Expand All @@ -14,4 +15,3 @@ address = "127.0.0.1"
port = 3001
max_connections = 1000
weight = 1

63 changes: 49 additions & 14 deletions src/config/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
//defines Config struct that holds list of structures, selected load balancer algorithm, and an algorithm object.
//! Configuration module for the Deston load balancer.
//!
//! This module handles parsing and managing configuration from TOML files.
//! It defines the configuration structure including load balancer settings,
//! backend servers, and algorithm selection.

use hyper::Uri;
use std::fs;
Expand All @@ -15,32 +19,42 @@ use crate::server::server::{Server, SyncServer};
//type alias for a thread-safe, synchronized Config using Arc and Mutex
pub type SyncConfig = Arc<Mutex<Config>>;

//enum for all the algorithm
/// Load balancing algorithm options
#[derive(Clone)]
pub enum Algorithm {
RoundRobin, //round robin
WeightedRoundRobin, //weighted round robin
IpHashing, //ip hashing
}

/// Load balancer layer mode
#[derive(Clone, Debug, PartialEq)]
pub enum LayerMode {
L4, // Layer 4 (TCP) load balancer
L7, // Layer 7 (HTTP) load balancer
}

/// Configuration structure for the load balancer
pub struct Config {
pub load_balancer_address: Uri, //address of load balancer
pub servers: Arc<Vec<SyncServer>>, //thread safe vector of servers
pub algorithm: Algorithm, //algorithm to pick server
#[allow(dead_code)]
pub algorithm: Algorithm, //algorithm to pick server
pub last_picked_index: usize, //index of last picked server
pub algorithm_object: Box<dyn AlgorithmTrait>, //algorithm object
pub layer_mode: LayerMode, //layer mode (L4 or L7)
}

impl Config {
//creates and returns a new Config
/// Creates and returns a new Config from a TOML file
pub fn new(config_path: &Path) -> Self {
//read contents of config file
let contents = fs::read_to_string(config_path).unwrap();
//parese config file contents
//parse config file contents
let values = contents.parse::<Table>().unwrap();

//get host name, port and algorithm of load balancer
let (load_balancer_host, load_balancer_port, algorithm) = {
let (load_balancer_host, load_balancer_port, algorithm, layer_mode) = {
if let Some(table) = values.get("load_balancer") {
let host = {
if let Some(Value::String(address)) = table.get("address") {
Expand All @@ -64,10 +78,17 @@ impl Config {
Algorithm::RoundRobin
}
};
(host, port, algorithm)
let layer = {
if let Some(Value::String(layer)) = table.get("layer") {
get_layer_mode(layer)
} else {
LayerMode::L4 // Default to L4 for backward compatibility
}
};
(host, port, algorithm, layer)
} else {
//if host not found in config
("localhost", &8080, Algorithm::RoundRobin)
("localhost", &8080, Algorithm::RoundRobin, LayerMode::L4)
}
};

Expand Down Expand Up @@ -153,21 +174,35 @@ impl Config {
Algorithm::IpHashing => Box::new(IpHashing::new()),
}
},
algorithm: algorithm,
algorithm,
last_picked_index: 0,
layer_mode,
}
}
}

//funciton to get Algorithm from string
fn get_algorithm(algorithm: &String) -> Algorithm {
if algorithm == "RoundRobin" {
//function to get Algorithm from string (case-insensitive)
fn get_algorithm(algorithm: &str) -> Algorithm {
let algo_lower = algorithm.to_lowercase();
if algo_lower == "roundrobin" || algo_lower == "round_robin" {
Algorithm::RoundRobin
} else if algorithm == "WeightedRoundRobin" {
} else if algo_lower == "weightedroundrobin" || algo_lower == "weighted_round_robin" {
Algorithm::WeightedRoundRobin
} else if algorithm == "IpHashing" {
} else if algo_lower == "iphashing" || algo_lower == "ip_hashing" {
Algorithm::IpHashing
} else {
Algorithm::RoundRobin
}
}

//function to get LayerMode from string (case-insensitive)
fn get_layer_mode(layer: &str) -> LayerMode {
let layer_lower = layer.to_lowercase();
if layer_lower == "l4" || layer_lower == "layer4" || layer_lower == "layer_4" {
LayerMode::L4
} else if layer_lower == "l7" || layer_lower == "layer7" || layer_lower == "layer_7" {
LayerMode::L7
} else {
LayerMode::L4 // Default to L4
}
}
1 change: 1 addition & 0 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#[allow(clippy::module_inception)]
pub mod config;
35 changes: 35 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Library exports for Deston load balancer
//
//! # Deston Load Balancer
//!
//! A high-performance Layer 4 (L4) and Layer 7 (L7) load balancer implementation.
//!
//! ## Modules
//!
//! - `config`: Configuration parsing and management
//! - `load_balancer`: Load balancer trait and implementations (Layer 4 and Layer 7)
//! - `server`: Backend server management and request handling
//!
//! ## Example
//!
//! ```no_run
//! use deston::config::config::Config;
//! use deston::load_balancer::load_balancer::LoadBalancer;
//! use deston::load_balancer::layer4::Layer4;
//! use std::path::Path;
//! use std::sync::{Arc, Mutex};
//!
//! #[tokio::main]
//! async fn main() {
//! let config = Config::new(Path::new("config.toml"));
//! let lb = Layer4::new(Arc::new(Mutex::new(config)));
//! let _ = lb.start().await;
//! }
//! ```

pub mod config;
pub mod load_balancer;
pub mod server;

// Re-export Arc for convenience
pub use std::sync::Arc;
11 changes: 8 additions & 3 deletions src/load_balancer/algorithm/algorithm.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
//defines algorithm trait, it provies the blueprint for creating, and picking servers
//! Algorithm trait definition.
//!
//! This module defines the Algorithm trait that all load balancing algorithms must implement.

use crate::Arc;
use std::net::SocketAddr;

use crate::server::server::SyncServer;

/// Algorithm trait for load balancing strategies
pub trait Algorithm: Send {
//returns new Algorithm struct
/// Creates a new instance of the algorithm
fn new() -> Self
where
Self: Sized;

//picks server based on algorithm and returns server index and server. returns None if no server available
/// Picks a server based on the algorithm's strategy
///
/// Returns Some((index, server)) if a server is available, None otherwise
fn pick_server(
&mut self,
servers: Arc<Vec<SyncServer>>,
Expand Down
1 change: 1 addition & 0 deletions src/load_balancer/algorithm/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
#[allow(clippy::module_inception)]
pub mod algorithm;
pub mod r#static;
6 changes: 5 additions & 1 deletion src/load_balancer/algorithm/static/ip_hashing.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
//defines ip hashing, where servers are selected based on client ip address
//! IP Hashing load balancing algorithm.
//!
//! Uses consistent hashing based on client IP addresses to ensure the same client
//! is always routed to the same backend server, providing session affinity.

use sha2::{Digest, Sha256};
use std::net::SocketAddr;
Expand All @@ -7,6 +10,7 @@ use std::sync::Arc;
use crate::load_balancer::algorithm::algorithm::Algorithm;
use crate::server::server::SyncServer;

/// IP Hashing algorithm implementation
pub struct IpHashing {}

impl Algorithm for IpHashing {
Expand Down
7 changes: 5 additions & 2 deletions src/load_balancer/algorithm/static/round_robin.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
//defines round robin algorithm, where servers are selected sequentially
//! Round Robin load balancing algorithm.
//!
//! Distributes requests evenly across all servers in a sequential, circular fashion.

use crate::Arc;
use std::net::SocketAddr;

use crate::load_balancer::algorithm::algorithm::Algorithm;
use crate::server::server::SyncServer;

/// Round Robin algorithm implementation
pub struct RoundRobin {
index: usize,
}
Expand All @@ -29,7 +32,7 @@ impl Algorithm for RoundRobin {
//pick server
let server = servers[self.index].clone();
let index = self.index;
//incriment index
//increment index
self.index = (self.index + 1) % servers.len();
//return index and server
Some((index, server))
Expand Down
6 changes: 5 additions & 1 deletion src/load_balancer/algorithm/static/weighted_round_robin.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
//defines weighted round robin algorithm, where servers are selected sequentially, taking their assigned weights into account. Servers with higher weights are picked more frequently
//! Weighted Round Robin load balancing algorithm.
//!
//! Distributes requests based on server weights. Servers with higher weights
//! receive proportionally more requests.

use std::net::SocketAddr;
use std::sync::Arc;

use crate::load_balancer::algorithm::algorithm::Algorithm;
use crate::server::server::SyncServer;

/// Weighted Round Robin algorithm implementation
pub struct WeightedRoundRobin {
index: usize,
curr_weight: usize,
Expand Down
Loading