{"id":23177317,"url":"https://github.com/abdo-reda/basicrustudpserver","last_synced_at":"2025-06-14T21:33:59.715Z","repository":{"id":150004053,"uuid":"584090904","full_name":"Abdo-reda/BasicRustUDPServer","owner":"Abdo-reda","description":"This is a simple basic server made in Rust which uses UDP","archived":false,"fork":false,"pushed_at":"2023-01-01T11:22:56.000Z","size":285,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-05T01:41:51.222Z","etag":null,"topics":["rust","server","udp-server"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Abdo-reda.png","metadata":{"files":{"readme":"ReadMe.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-01T10:08:31.000Z","updated_at":"2023-01-01T10:13:50.000Z","dependencies_parsed_at":"2023-08-24T19:32:40.091Z","dependency_job_id":null,"html_url":"https://github.com/Abdo-reda/BasicRustUDPServer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Abdo-reda/BasicRustUDPServer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Abdo-reda%2FBasicRustUDPServer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Abdo-reda%2FBasicRustUDPServer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Abdo-reda%2FBasicRustUDPServer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Abdo-reda%2FBasicRustUDPServer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Abdo-reda","download_url":"https://codeload.github.com/Abdo-reda/BasicRustUDPServer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Abdo-reda%2FBasicRustUDPServer/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259887603,"owners_count":22926965,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["rust","server","udp-server"],"created_at":"2024-12-18T06:32:58.836Z","updated_at":"2025-06-14T21:33:59.705Z","avatar_url":"https://github.com/Abdo-reda.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# What is this?\nThis is a simple Server and Client made in Rust which uses UDP. If you want to run, make sure to have [Rust](https://www.rust-lang.org/tools/install) installed first.\n* Important! You will have to manuallly update the ip addresses in both the client and server.\n* There is a report that contains a much more detailed explanation of the project.\n\n## Credits:\nThis was a university project, it was done with a group of three (me included!). Thanks for Ahmed Shaaban and N42at \u003c3.\n\n\n# Server(s):\nThere are two variations for the server. One does load balancing using round robin. The Other uses a threshold algorithm.\n\n## To Run:\n    $cargo Run \u003carg1\u003e \u003carg2\u003e\n\nThe Server takes in two arguments:\n* arg1: is the server id (please make sure to start from 0).\n* arg2: is the fileName that will store logs about the server.\n\n\n# Client(s):\nThe Client is a process which spawns 503 threads, 500 simulating different client applications, 2 threads for middleware and a thread for logging info.\n\n## To Run:\n    $cargo run \u003carg1\u003e \u003carg2\u003e \u003carg3\u003e\n\nThe Client takes in three arguments:\n* arg1: is the port the middleware will use to send messages/requests from.\n* arg2: is the port the middleware will use to recieve and send messages/announcments from and to other middlewares.\n* arg3: is the fileName that will store logs about the client.\n\n\n# Report\n\n# Distributed Systems Project Report\n\n## Team Members\n- **Abdullah Nashat Salman**   \n- **Ahmad Shaaban**  \n- **Abdelrahman Reda Abdelmonem** \n\n## Design\n![System Diagram](diagram.png)  \n*A simplified diagram of the system showing different nodes and their connections.*\n\n### **Client Side**\nThe client is implemented as a **single process with 503 threads**:\n- **`500` threads** represent client applications:\n  - Each thread executes an infinite loop, sending messages to the middleware thread and blocking for a reply.\n  - Every 20 seconds, a thread logs its metrics (requests made, latency, etc.) to the logging thread.\n- **`2` middleware threads**:\n  - **First thread**: Handles incoming messages from client threads.\n    - Uses round-robin to send requests to servers.\n    - Implements a 3-second timeout for server replies.\n    - Replies to the client thread with either the server's response or a failure message (-1).\n  - **Second thread**: Handles announcements from other middleware agents (e.g., server down notifications).\n    - Updates the list of available servers.\n- **`1` logging thread**:\n  - Logs thread metrics, calculates averages, and writes data to a file every 20 seconds.\n\n**Communication**: Rust's native `Channels` are used for thread communication, supporting synchronous/asynchronous messaging with multiple producers and a single consumer.\n\n---\n\n### **Server Side**\nThe server is implemented as a **single process with `n+3` threads** (where `n = 5` worker threads):\n- **`n` worker threads**:\n  - Each worker listens/blocks on a shared channel where jobs are queued. Once a job is available, it will try to consume and execute, and returns to blocking.\n  - The channel uses a mutex lock for thread-safe access.\n- **`1` listener thread (main)**:\n  - Blocks on `get_request`, queues incoming requests for workers.\n  - Handles \"down-announcement\" messages:\n    - If the server's ID matches the downed server's ID, it sleeps for `SLEEP_TIME`.\n    - Stops the election trigger thread to ensure only one server is down at a time.\n  - Measures load (requests/sec) and multicasts updates under threshold load balancing.\n- **`1` election trigger thread**:\n  - Attempts to start an election every `TRY_START_ELECTION_FREQ` ms with a `START_ELECTION_PROBABILITY` chance.\n  - If triggered, sends an election message to the next server in the ring.\n- **`1` logging thread**:\n  - Logs server load every second and downtime events.\n  - Maintains the 100 most recent log entries.\n\n**Shared Variables**: Server ID, load, and server states are shared across threads using `Arc` pointers with mutexes for write operations.\n\n\n\n## Algorithms\n### **Load Balancing**\n#### Round Robin\n- Each client middleware iterates over the server list in a loop.\n- Requests are sent to the next available server.\n\n#### Round Robin + Threshold\n- Servers classify their load into three levels:\n  - **0 (Underloaded)**: 0–5000 req/sec  \n  - **1 (Medium)**: 5000–7500 req/sec  \n  - **2 (Overloaded)**: 7500+ req/sec  \n- Servers multicast load updates every second. Overloaded servers forward requests to underloaded peers if possible.\n\n\n### **Distributed Election**\n#### Ring Algorithm\n- Servers are arranged in a logical ring.\n- An election trigger thread may start an election, propagating a message around the ring.\n- The message collects server IDs and random values; the initiator selects the server with the highest value to go down.\n- The chosen server sleeps for `SLEEP_TIME` (10 sec), and an announcement is multicast to all nodes.\n\n\n\n## Assumptions \u0026 Limitations\n- **Client**:\n  - Each thread blocks for replies with a 3-second timeout.\n- **Server**:\n  - Fixed 5 worker threads.\n- **Threshold**:\n  - Load levels are predefined; down servers cannot update their status.\n- **Election**:\n  - Only one server can be down at a time.\n  - Downed servers stop listening but finish pending requests.\n\n\n\n## Changes \u0026 Updates\n### **Client Side**\n- Evolved from a simple UDP client to a multithreaded system with:\n  - 500 client threads.\n  - Middleware for request handling and announcements.\n  - Logging for performance metrics.\n\n### **Server Side**\n- Expanded from a basic UDP server to include:\n  - Thread pools for request handling.\n  - Election and threshold load-balancing logic.\n  - Logging for load and downtime.\n\n\n## Issues \u0026 Obstacles\n### **Design Issues**\n- Initially planned separate client/middleware processes but switched to threads due to Rust's IPC complexity.\n- Solved thread-to-thread reply challenges by creating 500 dedicated channels.\n\n### **Technical Issues**\n- Global variable management.\n- Error handling (e.g., underflow/overflow).\n- Marshaling and time measurement complexities.\n\n\n\n## Metrics \u0026 Performance\n| Test Case               | Latency (ms) | Throughput (req/sec) | Failed Requests | Avg Load (0/1/2) |\n|-------------------------|--------------|-----------------------|------------------|-------------------|\n| 2 Clients, Round Robin | 61           | 8108                  | 1                | 4997/6630/7225    |\n| 1 Client, Round Robin  | 44           | 11140                 | 1                | 5681/6100/3989    |\n| 2 Clients, Threshold   | 66           | 7459                  | 13               | 19791/12932/6466  |\n| 1 Client, Threshold    | 44           | 11082                 | 1                | 4645/4200/4400    |\n\n### **Discussion**\n- **1 vs 2 Clients**: Fewer clients yield lower latency and higher throughput.\n- **Threshold vs Round Robin**: Threshold added overhead without performance gains in this simple system. Round robin was more efficient.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabdo-reda%2Fbasicrustudpserver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fabdo-reda%2Fbasicrustudpserver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabdo-reda%2Fbasicrustudpserver/lists"}