https://github.com/tobiadeniji94/token_ring_algorithm
The Token Ring System simulates a distributed environment where multiple processes coordinate access to a critical section using a token.
https://github.com/tobiadeniji94/token_ring_algorithm
algorithm java ring token
Last synced: 8 months ago
JSON representation
The Token Ring System simulates a distributed environment where multiple processes coordinate access to a critical section using a token.
- Host: GitHub
- URL: https://github.com/tobiadeniji94/token_ring_algorithm
- Owner: TobiAdeniji94
- License: mit
- Created: 2025-03-30T23:16:09.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2025-03-30T23:54:06.000Z (8 months ago)
- Last Synced: 2025-03-31T00:21:24.650Z (8 months ago)
- Topics: algorithm, java, ring, token
- Language: Java
- Homepage:
- Size: 19.5 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Token Ring System Documentation
## Overview
The Token Ring System simulates a distributed environment where multiple processes coordinate access to a critical section using a token. It uses a Lamport clock for timestamping and handles message communication using polymorphism rather than a switch-case statement. The system also demonstrates features such as mutual exclusion, coordinator election and failure detection, fairness in request handling, and process recovery.
**Note:** This implementation is based on the algorithm described in the paper *"Token Ring Algorithm To Achieve Mutual Exclusion In Distributed System – A Centralized Approach"* by Sandipan Basu, published in the *IJCSI International Journal of Computer Science Issues, Vol. 8, Issue 1, January 2011*
## Components
### 1. Message and Message Types
- **`enum MessageType`**
Defines the types of messages exchanged between processes:
- **`REQUEST`**: A process requests access to the critical section.
- **`GRANT`**: The coordinator grants the token to a requesting process.
- **`RELEASE`**: A process releases the token after exiting the critical section.
- **`WAIT`**: (Reserved for potential waiting functionality.)
- **`EXISTS`**: Used by processes to check if the coordinator is alive.
- **`OK`**: Acknowledgement message.
- **`COORDINATOR`**: Announces the new coordinator.
- **`UPDATE`**: (Reserved for updating ring configuration.)
- **`NEW`**: Used to add a new process to the ring configuration.
- **`class Message`**
Represents a communication message between processes. Key fields include:
- **`senderPid`**: The process identifier (PID) of the sender.
- **`type`**: The type of the message (from `MessageType`).
- **`timestamp`**: The Lamport clock timestamp when the message was created.
- **`coordinatorPid`**: For `COORDINATOR` messages, the PID of the elected coordinator.
- **`ringConfig`**: For `UPDATE` messages, holds the ring configuration (list of process IDs).
### 2. Lamport Clock
- **`class LamportClock`**
Implements a logical clock using Lamport’s algorithm:
- **`incrementAndGet()`**: Increments the clock and returns the new time.
- **`get()`**: Returns the current time.
- **`update(int receivedTime)`**: Updates the clock based on the received timestamp, ensuring the clock always advances.
### 3. Message Handlers
To avoid a central switch-case statement, the system uses polymorphism by defining a common interface and multiple concrete handler classes for different message types.
- **`interface MessageHandler`**
Declares a single method:
- **`void handle(Process process, Message msg)`**: Processes the given message using the context of the process.
- **Handler Implementations:**
- **`RequestHandler`**:
- Handles `REQUEST` messages by invoking `process.handleRequest(msg)`.
- **`GrantHandler`**:
- Handles `GRANT` messages by setting the token flag (`hasToken`) and initiating the critical section via `process.startCriticalSection()`.
- **`ExistsHandler`**:
- Handles `EXISTS` messages by calling `process.handleExists(msg)`.
- **`ReleaseHandler`**:
- Handles `RELEASE` messages by calling `process.handleRelease(msg)`.
- **`NewHandler`**:
- Handles `NEW` messages by adding a new process to the ring configuration if the process is the coordinator.
- **`NoOpHandler`**:
- A no-operation handler (used for `OK` messages).
- **`CoordinatorHandler`**:
- Handles `COORDINATOR` messages by updating the process’s coordinator information.
### 4. Process Class
- **`class Process implements Runnable`**
Represents a node in the distributed system. Key responsibilities include:
- **State Variables:**
- `pid`: Unique identifier for the process.
- `coordinatorPid`: PID of the current coordinator.
- `clock`: Instance of `LamportClock` for managing timestamps.
- `requestQueue`: A priority queue that orders `REQUEST` messages by timestamp and sender PID.
- `ringConfig`: A list of process IDs representing the token ring.
- `inbox`: A blocking queue to store incoming messages.
- `scheduler`: Schedules tasks such as sending periodic EXISTS messages or checking coordinator status.
- Flags like `hasToken`, `isCoordinator`, and `inCriticalSection` manage process state.
- **Message Handling:**
A map (`messageHandlers`) associates each `MessageType` with its corresponding `MessageHandler`. In the main `run()` loop, each incoming message is delegated to the appropriate handler.
- **Key Methods:**
- **`send(Message msg)`**: Adds a message to the process's inbox.
- **`sendToCoordinator(Message msg)`**: Sends a message directly to the coordinator.
- **`broadcast(Message msg)`**: Sends a message to all processes in the system.
- **`handleRequest(Message msg)`**: Adds a request to the queue and may trigger token granting.
- **`grantToken()`**: Grants the token to the next process in the request queue.
- **`handleExists(Message msg)`**: Handles EXISTS messages to confirm the coordinator is alive.
- **`handleRelease(Message msg)`**: Processes RELEASE messages by freeing up the token.
- **`becomeCoordinator()`**: Transitions the process to a coordinator role if a failure is detected.
- **`checkCoordinatorAlive()`**: Periodically checks the health of the current coordinator.
- **`startCriticalSection()`**: Simulates the execution of the critical section.
- **`requestCriticalSection()`**: Sends a REQUEST message to the coordinator to enter the critical section.
### 5. TokenRingSystem
- **`class TokenRingSystem`**
Manages the overall simulation:
- **Static List:**
- `List processes`: Holds all process instances.
- **`main(String[] args)`**:
- Creates a predefined number of processes.
- Starts each process using an executor service.
- Initiates a test sequence that simulates:
- **Test 1: Mutual Exclusion** – Random processes request access to the critical section.
- **Test 2: Coordinator Failure** – The coordinator is deliberately failed to test recovery.
- **Test 3: Fairness** – Specific processes are forced to request the critical section.
- **Test 4: Process Recovery** – A previously failed process is revived and reintegrated into the ring.
## How It Works
1. **Initialization:**
The `TokenRingSystem` initializes multiple `Process` objects, assigns one as the coordinator, and sets up the ring configuration.
2. **Message Delegation:**
Each process’s `run()` method continuously polls its inbox for messages. Using a handler map, the system delegates the processing of each message to its corresponding handler, which executes the relevant logic (e.g., handling requests, granting tokens, or processing coordinator updates).
3. **Critical Section Access:**
When a process requests access via `requestCriticalSection()`, it sends a `REQUEST` message. The coordinator, maintaining a request queue, eventually sends a `GRANT` message (if it has the token), allowing the process to enter its critical section.
4. **Coordinator Failure and Recovery:**
The system periodically checks if the coordinator is still alive. If the coordinator fails, another process can become the new coordinator by calling `becomeCoordinator()`. Additionally, the `NEW` message type supports the addition or recovery of processes into the ring configuration.
## Usage
- **Running the System:**
Execute the `main()` method in the `TokenRingSystem` class. The system will start all processes and run through a sequence of tests simulating:
- Mutual exclusion by randomly requesting the critical section.
- Coordinator failure and subsequent recovery.
- Fairness in servicing requests.
- Process recovery and reintegration.
- **Console Output:**
The system prints detailed status messages to the console. These messages trace:
- Requests for critical section entry.
- Token grants by the coordinator.
- Processes entering and leaving the critical section.
- Coordinator failure detection and election.
- Process recovery events.
## Acknowledgments and References
This implementation is based on the algorithm presented in:
> **Sandipan Basu, "Token Ring Algorithm To Achieve Mutual Exclusion In Distributed System – A Centralized Approach."**
> *IJCSI International Journal of Computer Science Issues, Vol. 8, Issue 1, January 2011.*
> ISSN (Online): 1694-0814
> [www.IJCSI.org](http://www.IJCSI.org)
>
> The paper addresses challenges in ensuring mutual exclusion in distributed systems. It proposes enhancements to the traditional token ring algorithm—special thanks to Sandipan Basu for his contributions to the field.