diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/ARCHITECTURE.md | 397 | ||||
| -rw-r--r-- | docs/DEVELOPER_GUIDE.md | 537 | ||||
| -rw-r--r-- | docs/TIMESTAMP_EVENTS_GUIDE.md | 293 | ||||
| -rw-r--r-- | docs/architecture-diagrams.puml | 390 |
4 files changed, 1617 insertions, 0 deletions
diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..f222850 --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,397 @@ +# DS-Sim Architecture Documentation + +## Table of Contents +1. [Overview](#overview) +2. [Core Architecture](#core-architecture) +3. [Event-Driven Design](#event-driven-design) +4. [Protocol Framework](#protocol-framework) +5. [Time Management](#time-management) +6. [Message System](#message-system) +7. [Component Diagrams](#component-diagrams) +8. [Sequence Diagrams](#sequence-diagrams) + +## Overview + +DS-Sim is an event-driven distributed systems simulator built with Java. It provides a visual environment for simulating and understanding distributed algorithms, protocols, and time synchronization mechanisms. + +### Key Design Principles +- **Event-Driven Architecture**: All actions are modeled as events +- **Pluggable Protocols**: Easy to add new distributed algorithms +- **Visual Feedback**: Real-time visualization of process states and messages +- **Time Simulation**: Support for logical clocks and clock drift + +## Core Architecture + +### Layer Diagram +``` +┌─────────────────────────────────────────────────────────────┐ +│ User Interface Layer │ +│ VSSimulatorFrame, VSSimulator, VSSimulatorVisualization │ +├─────────────────────────────────────────────────────────────┤ +│ Protocol Layer │ +│ VSAbstractProtocol, Protocol Implementations │ +├─────────────────────────────────────────────────────────────┤ +│ Event System Layer │ +│ VSAbstractEvent, VSTask, VSTaskManager │ +├─────────────────────────────────────────────────────────────┤ +│ Core Process Layer │ +│ VSAbstractProcess, VSInternalProcess, VSMessage │ +├─────────────────────────────────────────────────────────────┤ +│ Infrastructure Layer │ +│ Time Management, Serialization, Utilities │ +└─────────────────────────────────────────────────────────────┘ +``` + +### Component Overview + +```mermaid +graph TB + subgraph UI[User Interface] + Frame[VSSimulatorFrame] + Sim[VSSimulator] + Viz[VSSimulatorVisualization] + end + + subgraph Core[Core Components] + TM[VSTaskManager] + IP[VSInternalProcess] + Msg[VSMessage] + end + + subgraph Events[Event System] + AE[VSAbstractEvent] + Task[VSTask] + RE[VSRegisteredEvents] + end + + subgraph Protocols[Protocols] + AP[VSAbstractProtocol] + PP[PingPongProtocol] + BC[BroadcastProtocol] + TC[TwoPhaseCommit] + end + + Frame --> Sim + Sim --> Viz + Viz --> TM + TM --> Task + Task --> AE + IP --> Msg + AP --> AE + PP --> AP + BC --> AP + TC --> AP +``` + +## Event-Driven Design + +The simulator operates on an event-driven model where all actions are encapsulated as events that are scheduled and executed by the task manager. + +### Event Hierarchy + +```mermaid +classDiagram + class VSAbstractEvent { + <<abstract>> + +onInit() + +onStart() + +getClassname() + +isInternalEvent() + +shouldIncreaseTimestamps() + } + + class VSAbstractProtocol { + <<abstract>> + +onServerInit() + +onClientInit() + +onServerRecv() + +onClientRecv() + +sendMessage() + } + + class VSProcessCrashEvent { + +onStart() + } + + class VSMessageReceiveEvent { + +onStart() + } + + class VSTimestampTriggeredEvent { + <<abstract>> + +checkCondition() + +onTimestampReached() + } + + VSAbstractEvent <|-- VSAbstractProtocol + VSAbstractEvent <|-- VSProcessCrashEvent + VSAbstractEvent <|-- VSMessageReceiveEvent + VSAbstractEvent <|-- VSTimestampTriggeredEvent +``` + +### Event Lifecycle + +1. **Creation**: Events are created with specific parameters +2. **Initialization**: `onInit()` is called once when first added +3. **Scheduling**: Events are wrapped in `VSTask` with execution time +4. **Execution**: `onStart()` is called when scheduled time arrives +5. **Completion**: Event completes or schedules new events + +## Protocol Framework + +Protocols implement distributed algorithms and define client-server communication patterns. + +### Protocol Structure + +```mermaid +stateDiagram-v2 + [*] --> Uninitialized + Uninitialized --> ServerInit: isServer + Uninitialized --> ClientInit: isClient + + ServerInit --> ServerReady + ClientInit --> ClientReady + + ServerReady --> ServerStart: hasOnServerStart + ClientReady --> ClientStart: !hasOnServerStart + + ServerReady --> ServerRecv: receive message + ClientReady --> ClientRecv: receive message + + ServerReady --> ServerSchedule: scheduled event + ClientReady --> ClientSchedule: scheduled event +``` + +### Protocol Implementation Pattern + +```java +public class MyProtocol extends VSAbstractProtocol { + public MyProtocol() { + super(HAS_ON_SERVER_START); // or HAS_ON_CLIENT_START + } + + // Server-side methods + public void onServerInit() { /* Initialize server state */ } + public void onServerStart() { /* Server begins protocol */ } + public void onServerRecv(VSMessage msg) { /* Handle client message */ } + public void onServerSchedule() { /* Periodic server action */ } + + // Client-side methods + public void onClientInit() { /* Initialize client state */ } + public void onClientStart() { /* Client begins protocol */ } + public void onClientRecv(VSMessage msg) { /* Handle server message */ } + public void onClientSchedule() { /* Periodic client action */ } +} +``` + +## Time Management + +The simulator supports multiple time representations for distributed systems research. + +### Time Types + +```mermaid +graph LR + subgraph Time System + GT[Global Time<br/>Simulation Clock] + LT[Local Time<br/>Process Clock] + LAM[Lamport Time<br/>Logical Clock] + VT[Vector Time<br/>Vector Clock] + end + + GT --> LT + LT --> LAM + LT --> VT +``` + +### Clock Synchronization + +- **Global Time**: Absolute simulation time (milliseconds) +- **Local Time**: Process time with configurable drift +- **Lamport Time**: Increments on events and messages +- **Vector Time**: Array of logical times for each process + +### Clock Drift Simulation + +``` +Local Time = Global Time + Accumulated Drift +Drift Rate = Clock Variance (e.g., -0.1 to +0.1) +``` + +## Message System + +Messages in DS-Sim carry protocol data between processes with automatic timestamp management. + +### Message Flow + +```mermaid +sequenceDiagram + participant P1 as Process 1 + participant TM as TaskManager + participant Net as Network Sim + participant P2 as Process 2 + + P1->>P1: Increase timestamps + P1->>TM: Create send task + TM->>Net: Schedule with delay + Net->>TM: Create receive task + TM->>P2: Deliver message + P2->>P2: Update timestamps + P2->>P2: Process message +``` + +### Message Properties + +- **Sender/Receiver**: Process IDs +- **Protocol**: Associated protocol class +- **Timestamps**: Lamport and vector times +- **Payload**: Serializable data +- **Type**: Server or client message + +## Component Diagrams + +### Task Management System + +```mermaid +graph TB + subgraph TaskManager + PQ[Priority Queue<br/>Time-ordered tasks] + GL[Global Tasks<br/>Simulation time] + LL[Local Tasks<br/>Process time] + end + + subgraph Task Execution + Run[runTasks<br/>Main loop] + Exec[Execute task] + Update[Update times] + end + + PQ --> Run + Run --> Exec + Exec --> Update + Update --> PQ +``` + +### Process Architecture + +```mermaid +classDiagram + class VSAbstractProcess { + <<abstract>> + #localTime: long + #globalTime: long + #lamportTime: long + #vectorTime: VSVectorTime + +increaseTime() + +sendMessage() + } + + class VSInternalProcess { + -clockVariance: float + -clockOffset: double + -vectorClockMonitor: VSVectorClockMonitor + +syncTime(globalTime) + +highlightOn() + +crash() + +recover() + } + + VSAbstractProcess <|-- VSInternalProcess +``` + +## Sequence Diagrams + +### Protocol Initialization + +```mermaid +sequenceDiagram + participant UI as User Interface + participant Reg as VSRegisteredEvents + participant Proto as Protocol + participant Proc as Process + + UI->>Reg: Select protocol + Reg->>Proto: Create instance + Proto->>Proc: Set process + Proc->>Proto: isServer(true/false) + Proto->>Proto: onServerInit/onClientInit + Proto->>UI: Ready +``` + +### Event Processing Loop + +```mermaid +sequenceDiagram + participant Viz as Visualization + participant TM as TaskManager + participant Task as VSTask + participant Event as Event + participant Proc as Process + + loop Simulation Loop + Viz->>TM: runTasks(currentTime) + TM->>TM: Get ready tasks + TM->>Task: run() + Task->>Event: onStart() + Event->>Proc: Update state + Event->>TM: Schedule new tasks + end +``` + +### Two-Phase Commit Example + +```mermaid +sequenceDiagram + participant Coord as Coordinator + participant P1 as Process 1 + participant P2 as Process 2 + + Coord->>P1: VOTE_REQUEST + Coord->>P2: VOTE_REQUEST + P1->>Coord: VOTE_YES + P2->>Coord: VOTE_YES + Coord->>Coord: All votes YES + Coord->>P1: GLOBAL_COMMIT + Coord->>P2: GLOBAL_COMMIT + P1->>Coord: ACK + P2->>Coord: ACK +``` + +## Adding New Components + +### Creating a New Event + +1. Extend `VSAbstractEvent` +2. Implement `onInit()` and `onStart()` +3. Register in `VSRegisteredEvents.init()` + +### Creating a New Protocol + +1. Extend `VSAbstractProtocol` +2. Implement required abstract methods +3. Choose `HAS_ON_SERVER_START` or `HAS_ON_CLIENT_START` +4. Register in `VSRegisteredEvents.init()` + +### Creating Timestamp-Triggered Events + +1. Extend `VSTimestampTriggeredEvent` +2. Implement `onTimestampReached()` +3. Configure trigger conditions +4. Register with process monitor + +## Design Patterns Used + +- **Template Method**: Protocol base class defines structure +- **Observer**: Event system for loose coupling +- **Strategy**: Pluggable protocols and events +- **Factory**: Event creation through registry +- **Singleton**: Global registries and managers +- **Command**: Events encapsulate actions + +## Future Architecture Improvements + +1. **GUI Separation**: Extract UI from business logic +2. **Dependency Injection**: Remove static registries +3. **Event Bus**: Decouple component communication +4. **Plugin System**: Dynamic protocol loading +5. **Reactive Streams**: Modern async event handling
\ No newline at end of file diff --git a/docs/DEVELOPER_GUIDE.md b/docs/DEVELOPER_GUIDE.md new file mode 100644 index 0000000..ed0f8e1 --- /dev/null +++ b/docs/DEVELOPER_GUIDE.md @@ -0,0 +1,537 @@ +# DS-Sim Developer Guide + +This guide explains how to extend DS-Sim with new protocols, events, and features. + +## Table of Contents +1. [Creating a New Protocol](#creating-a-new-protocol) +2. [Creating Custom Events](#creating-custom-events) +3. [Working with Time and Timestamps](#working-with-time-and-timestamps) +4. [Message Passing](#message-passing) +5. [Testing Your Components](#testing-your-components) +6. [Best Practices](#best-practices) + +## Creating a New Protocol + +### Step 1: Understand the Protocol Framework + +All protocols extend `VSAbstractProtocol` and must implement both server and client sides, even if one side does nothing. The framework supports two initialization patterns: + +- **Server-initiated**: Protocol starts from server side (`HAS_ON_SERVER_START = true`) +- **Client-initiated**: Protocol starts from client side (`HAS_ON_CLIENT_START = false`) + +### Step 2: Create Your Protocol Class + +```java +package protocols.implementations; + +import core.VSMessage; +import protocols.VSAbstractProtocol; + +public class VSMyProtocol extends VSAbstractProtocol { + + // Protocol-specific constants + private static final String MSG_REQUEST = "REQUEST"; + private static final String MSG_RESPONSE = "RESPONSE"; + + // State variables (separate for client/server) + private int serverState; + private int clientState; + + public VSMyProtocol() { + // true = server starts, false = client starts + super(HAS_ON_SERVER_START); + } + + // Server-side implementation + @Override + public void onServerInit() { + // Initialize server state + serverState = 0; + // Set any server preferences + setBoolean("myprotocol.server.enabled", true); + } + + @Override + public void onServerStart() { + // Server initiates the protocol + VSMessage msg = new VSMessage(); + msg.setString("type", MSG_REQUEST); + msg.setInteger("value", 42); + sendMessage(msg); // Broadcasts to all clients + } + + @Override + public void onServerRecv(VSMessage message) { + // Handle messages from clients + String type = message.getString("type"); + if (MSG_RESPONSE.equals(type)) { + int clientId = message.getSenderNum(); + int value = message.getInteger("value"); + process.log("Received response from client " + clientId + ": " + value); + } + } + + @Override + public void onServerSchedule() { + // Called when a scheduled server event fires + // Schedule periodic actions using scheduleAt(time) + } + + @Override + public void onServerReset() { + // Clean up server state + serverState = 0; + } + + // Client-side implementation + @Override + public void onClientInit() { + // Initialize client state + clientState = 0; + setBoolean("myprotocol.client.autorespond", true); + } + + @Override + public void onClientStart() { + // Only called if HAS_ON_CLIENT_START = false + } + + @Override + public void onClientRecv(VSMessage message) { + // Handle messages from server + String type = message.getString("type"); + if (MSG_REQUEST.equals(type)) { + int value = message.getInteger("value"); + + // Process the request + clientState = value * 2; + + // Send response + VSMessage response = new VSMessage(); + response.setString("type", MSG_RESPONSE); + response.setInteger("value", clientState); + sendMessage(response); + } + } + + @Override + public void onClientSchedule() { + // Called when a scheduled client event fires + } + + @Override + public void onClientReset() { + // Clean up client state + clientState = 0; + } +} +``` + +### Step 3: Register Your Protocol + +Add your protocol to `VSRegisteredEvents.init()`: + +```java +public static void init(VSPrefs prefs_) { + // ... existing registrations ... + registerEvent("protocols.implementations.VSMyProtocol"); +} +``` + +### Step 4: Protocol Communication Patterns + +#### Broadcast (Server to All Clients) +```java +// In server code +VSMessage msg = new VSMessage(); +sendMessage(msg); // Automatically sent to all clients +``` + +#### Unicast (Client to Server) +```java +// In client code +VSMessage msg = new VSMessage(); +sendMessage(msg); // Automatically sent to server only +``` + +#### Selective Send (Server to Specific Client) +```java +// In server code - requires custom handling +VSMessage msg = new VSMessage(); +msg.setInteger("targetClient", 2); // Custom field +sendMessage(msg); // Clients must filter +``` + +### Step 5: Using Scheduled Events + +```java +// Schedule a task to run at local time 1000 +scheduleAt(1000); + +// This will trigger onServerSchedule() or onClientSchedule() +@Override +public void onServerSchedule() { + // Periodic action + process.log("Scheduled event triggered"); + + // Reschedule for next interval + long nextTime = process.getTime() + 500; + scheduleAt(nextTime); +} +``` + +## Creating Custom Events + +### Basic Event + +```java +package events.implementations; + +import events.VSAbstractEvent; + +public class VSMyEvent extends VSAbstractEvent { + + private String eventData; + + @Override + public void onInit() { + // Called once when event is first created + setClassname(getClass().getName()); + eventData = getString("myevent.data", "default"); + } + + @Override + public void onStart() { + // Called when event executes + process.log("MyEvent executing with data: " + eventData); + + // Optionally schedule another event + VSMyEvent nextEvent = new VSMyEvent(); + VSTask task = new VSTask( + process.getTime() + 100, // When to execute + process, // Which process + nextEvent, // What event + VSTask.LOCAL // LOCAL or GLOBAL time + ); + // Add task through simulator + } + + @Override + protected String createShortname(String savedShortname) { + return "MyEvent"; + } +} +``` + +### Copyable Event + +```java +public class VSCopyableMyEvent extends VSAbstractEvent implements VSCopyableEvent { + + private int counter; + + @Override + public void initCopy(VSAbstractEvent copy) { + if (copy instanceof VSCopyableMyEvent) { + VSCopyableMyEvent myCopy = (VSCopyableMyEvent) copy; + myCopy.counter = this.counter; + } + } + + // ... rest of implementation +} +``` + +### Timestamp-Triggered Event + +```java +public class VSCustomTimestampEvent extends VSTimestampTriggeredEvent { + + public VSCustomTimestampEvent() { + // Trigger when Lamport time >= 50 + super(50, ComparisonOperator.GREATER_EQUAL); + } + + @Override + protected void onTimestampReached() { + // This fires when condition is met + process.log("Lamport time reached 50!"); + + // Highlight process + if (process instanceof VSInternalProcess) { + ((VSInternalProcess) process).highlightOn(); + } + } +} +``` + +## Working with Time and Timestamps + +### Time Types in DS-Sim + +1. **Global Time**: Simulation-wide clock (milliseconds) +2. **Local Time**: Per-process clock with drift +3. **Lamport Time**: Logical timestamp for ordering +4. **Vector Time**: Vector clock for causality + +### Accessing Time Values + +```java +// In a protocol or event +long globalTime = process.getGlobalTime(); +long localTime = process.getTime(); // Local time +long lamportTime = process.getLamportTime(); +VSVectorTime vectorTime = process.getVectorTime(); + +// Increase timestamps (done automatically for messages) +process.increaseLamportTime(); +process.increaseVectorTime(); +``` + +### Clock Drift Simulation + +```java +// In VSInternalProcess configuration +setFloat("process.clock.variance", 0.1f); // 10% drift +``` + +## Message Passing + +### Message Structure + +```java +// Creating a message +VSMessage msg = new VSMessage(); + +// Set data - supports various types +msg.setString("type", "REQUEST"); +msg.setInteger("sequence", 42); +msg.setBoolean("urgent", true); +msg.setFloat("value", 3.14f); +msg.setLong("timestamp", System.currentTimeMillis()); + +// Get data +String type = msg.getString("type"); +int seq = msg.getInteger("sequence", 0); // With default +``` + +### Message Metadata + +```java +// In receiver +int sender = message.getSenderNum(); +int receiver = message.getReceiverNum(); +VSLamportTime msgLamport = message.getLamportTime(); +VSVectorTime msgVector = message.getVectorTime(); +``` + +### Complex Data in Messages + +```java +// For complex data, convert to string +JSONObject data = new JSONObject(); +data.put("items", new JSONArray(items)); +msg.setString("data", data.toString()); + +// Or implement custom serialization +msg.setInteger("arraySize", array.length); +for (int i = 0; i < array.length; i++) { + msg.setInteger("array_" + i, array[i]); +} +``` + +## Testing Your Components + +### Unit Testing a Protocol + +```java +@Test +public void testProtocolServerInit() { + // Setup + VSPrefs prefs = new VSPrefs(); + VSInternalProcess process = mock(VSInternalProcess.class); + when(process.getNum()).thenReturn(0); + + // Create protocol + VSMyProtocol protocol = new VSMyProtocol(); + protocol.setProcess(process); + protocol.setPrefs(prefs); + protocol.isServer(true); + + // Test initialization + protocol.onInit(); + + // Verify state + assertTrue(prefs.getBoolean("myprotocol.server.enabled")); +} + +@Test +public void testMessageHandling() { + // Setup protocol and process + VSMyProtocol protocol = new VSMyProtocol(); + protocol.setProcess(mockProcess); + protocol.isClient(true); + protocol.onInit(); + + // Create test message + VSMessage msg = new VSMessage(); + msg.setString("type", "REQUEST"); + msg.setInteger("value", 10); + + // Test message handling + protocol.onClientRecv(msg); + + // Verify response was sent + verify(mockProcess).sendMessage(any(VSMessage.class)); +} +``` + +### Integration Testing + +```java +@Test +public void testProtocolIntegration() { + // Create simulator components + VSSimulatorVisualization viz = new VSSimulatorVisualization(); + VSTaskManager taskManager = new VSTaskManager(viz); + + // Create processes + VSInternalProcess server = createProcess(0, viz); + VSInternalProcess client1 = createProcess(1, viz); + VSInternalProcess client2 = createProcess(2, viz); + + // Setup protocol on all processes + setupProtocol(server, true, false); // server + setupProtocol(client1, false, true); // client + setupProtocol(client2, false, true); // client + + // Run simulation steps + for (int i = 0; i < 10; i++) { + taskManager.runTasks(i * 100); + } + + // Verify expected behavior + // Check logs, state changes, etc. +} +``` + +## Best Practices + +### 1. State Management + +- Keep server and client state separate +- Use preferences (VSPrefs) for configurable values +- Reset state properly in onReset methods + +### 2. Error Handling + +```java +@Override +public void onServerRecv(VSMessage message) { + try { + String type = message.getString("type"); + if (type == null) { + process.log("Warning: Received message without type"); + return; + } + // Process message + } catch (Exception e) { + VSErrorHandler.handle(e, "Error processing message"); + } +} +``` + +### 3. Logging + +```java +// Use process.log for important events +process.log("Protocol started"); + +// Add context to logs +process.log(String.format("Received %s from process %d", + msgType, message.getSenderNum())); + +// Debug logging +if (getBoolean("debug.verbose")) { + process.log("Debug: " + detailedInfo); +} +``` + +### 4. Performance Considerations + +- Avoid scheduling too many events +- Use appropriate time types (LOCAL vs GLOBAL) +- Clean up completed tasks and state +- Be mindful of message size + +### 5. Protocol Design + +- Document message types and formats +- Handle missing or malformed messages gracefully +- Consider network failures and timeouts +- Test with various numbers of processes + +### 6. Code Organization + +``` +protocols/implementations/ +├── VSMyProtocol.java # Main protocol implementation +├── messages/ # Message type constants +│ └── MyProtocolMessages.java +└── state/ # Complex state management + └── MyProtocolState.java +``` + +## Common Patterns + +### Request-Response Pattern + +```java +// Server sends request with ID +msg.setInteger("requestId", nextRequestId++); +pendingRequests.put(requestId, new RequestInfo()); + +// Client echoes ID in response +response.setInteger("requestId", message.getInteger("requestId")); + +// Server matches response to request +int requestId = message.getInteger("requestId"); +RequestInfo info = pendingRequests.remove(requestId); +``` + +### Timeout Handling + +```java +// Schedule timeout when sending request +long timeout = process.getTime() + 5000; +scheduleAt(timeout); +markTimeout(timeout, requestId); + +// In onSchedule, check for timeouts +if (isTimeout(process.getTime())) { + handleTimeout(); +} +``` + +### State Machine Implementation + +```java +enum ProtocolState { + INIT, WAITING, PROCESSING, DONE +} + +private ProtocolState state = ProtocolState.INIT; + +@Override +public void onServerRecv(VSMessage message) { + switch (state) { + case INIT: + handleInit(message); + break; + case WAITING: + handleWaiting(message); + break; + // etc. + } +} +```
\ No newline at end of file diff --git a/docs/TIMESTAMP_EVENTS_GUIDE.md b/docs/TIMESTAMP_EVENTS_GUIDE.md new file mode 100644 index 0000000..67ba2c0 --- /dev/null +++ b/docs/TIMESTAMP_EVENTS_GUIDE.md @@ -0,0 +1,293 @@ +# Timestamp-Triggered Events Guide + +This guide explains how to use DS-Sim's timestamp-triggered event system to create events that fire based on logical time conditions. + +## Overview + +Timestamp-triggered events allow you to: +- Fire events when Lamport timestamps reach specific values +- Trigger actions based on vector clock conditions +- Create complex temporal conditions for distributed algorithms +- Visualize causality and ordering in distributed systems + +## Event Types + +### 1. VSLamportTimestampEvent + +Triggers based on Lamport logical clock conditions. + +```java +// Fire when Lamport time reaches exactly 100 +VSLamportTimestampEvent event1 = new VSLamportTimestampEvent( + 100, ComparisonOperator.EQUAL, "Reached checkpoint" +); + +// Fire when Lamport time exceeds 50 +VSLamportTimestampEvent event2 = new VSLamportTimestampEvent( + 50, ComparisonOperator.GREATER_THAN, "Passed threshold" +); + +// With custom action +VSLamportTimestampEvent event3 = new VSLamportTimestampEvent( + 200, ComparisonOperator.GREATER_EQUAL, "Major milestone", + () -> { + System.out.println("Milestone reached!"); + // Custom logic here + } +); +``` + +### 2. VSVectorTimestampEvent + +Triggers based on vector clock conditions. + +```java +// Create target vector time [10, 5, 8] +VSVectorTime targetVector = new VSVectorTime(3); +targetVector.set(0, 10); +targetVector.set(1, 5); +targetVector.set(2, 8); + +// Fire when vector time equals target +VSVectorTimestampEvent event1 = new VSVectorTimestampEvent( + targetVector, ComparisonOperator.EQUAL, "Vectors synchronized" +); + +// Fire when current vector >= target (happens-before relation) +VSVectorTimestampEvent event2 = new VSVectorTimestampEvent( + targetVector, ComparisonOperator.GREATER_EQUAL, "Causality met" +); +``` + +### 3. VSTimestampMonitorEvent + +Monitors multiple timestamp conditions simultaneously. + +```java +VSTimestampMonitorEvent monitor = new VSTimestampMonitorEvent(); + +// Add multiple Lamport conditions +monitor.addLamportEvent(new VSLamportTimestampEvent( + 10, ComparisonOperator.EQUAL, "Early checkpoint" +)); +monitor.addLamportEvent(new VSLamportTimestampEvent( + 50, ComparisonOperator.GREATER_THAN, "Mid checkpoint" +)); + +// Add vector conditions +monitor.addVectorEvent(new VSVectorTimestampEvent( + targetVector, ComparisonOperator.EQUAL, "Vector match" +)); +``` + +## Comparison Operators + +| Operator | Symbol | Description | Example | +|----------|--------|-------------|---------| +| EQUAL | == | Exact match | Lamport == 100 | +| GREATER_THAN | > | Strictly greater | Lamport > 50 | +| LESS_THAN | < | Strictly less | Lamport < 30 | +| GREATER_EQUAL | >= | Greater or equal | Lamport >= 75 | +| LESS_EQUAL | <= | Less or equal | Lamport <= 25 | + +## Vector Clock Comparisons + +Vector clock comparisons follow the happens-before relation: + +- **Equal**: All components are equal +- **Greater**: v1 >= v2 in all components AND v1 > v2 in at least one +- **Less**: v2 > v1 (inverse of greater) +- **Concurrent**: Neither v1 > v2 nor v2 > v1 + +## Usage Examples + +### Example 1: Debugging Protocol Synchronization + +```java +// In your protocol initialization +public void onServerInit() { + // Fire when all clients have caught up + VSVectorTime syncPoint = new VSVectorTime(getNumProcesses()); + for (int i = 0; i < getNumProcesses(); i++) { + syncPoint.set(i, 10); // All processes at time 10 + } + + VSVectorTimestampEvent syncEvent = new VSVectorTimestampEvent( + syncPoint, ComparisonOperator.GREATER_EQUAL, + "All processes synchronized" + ); + + // Register with process + VSInternalProcess internal = (VSInternalProcess) process; + internal.getVectorClockMonitor().registerVectorEvent(syncEvent); +} +``` + +### Example 2: Phased Protocol Execution + +```java +public class PhasedProtocol extends VSAbstractProtocol { + + @Override + public void onServerInit() { + // Phase 1: Initialization (Lamport 0-20) + schedulePhase(20, "Phase 1 complete", this::startPhase2); + + // Phase 2: Data exchange (Lamport 21-50) + schedulePhase(50, "Phase 2 complete", this::startPhase3); + + // Phase 3: Finalization (Lamport > 50) + schedulePhase(100, "Protocol complete", this::finishProtocol); + } + + private void schedulePhase(long timestamp, String desc, Runnable action) { + VSLamportTimestampEvent phase = new VSLamportTimestampEvent( + timestamp, ComparisonOperator.GREATER_EQUAL, desc, action + ); + + // Add to process's task manager + VSTask task = new VSTask(0, process, phase, VSTask.LOCAL); + // ... add task to manager + } +} +``` + +### Example 3: Detecting Causality Violations + +```java +// Monitor for out-of-order message delivery +VSTimestampMonitorEvent causalityMonitor = new VSTimestampMonitorEvent() { + @Override + protected void onTimestampReached() { + // Check if vector times indicate causality violation + VSVectorTime current = process.getVectorTime(); + VSVectorTime expected = getExpectedVector(); + + if (!isValidCausalOrder(current, expected)) { + process.log("WARNING: Causality violation detected!"); + highlightProcess(); + } + } +}; +``` + +### Example 4: Performance Benchmarking + +```java +// Measure time to reach consensus +long startGlobal = process.getGlobalTime(); + +VSLamportTimestampEvent consensusReached = new VSLamportTimestampEvent( + CONSENSUS_LAMPORT_TIME, + ComparisonOperator.EQUAL, + "Consensus reached", + () -> { + long elapsed = process.getGlobalTime() - startGlobal; + process.log("Consensus took " + elapsed + "ms global time"); + process.log("Lamport time: " + process.getLamportTime()); + } +); +``` + +## Implementation Details + +### Registration and Monitoring + +1. **Process Registration**: Events are registered with the process +2. **Continuous Monitoring**: Vector events are checked on every vector clock update +3. **One-Time Trigger**: Events fire only once when condition is first met +4. **No Retroactive Firing**: Events won't fire if condition was already true + +### Memory Considerations + +- Events are kept in memory until triggered +- Use `reset()` to reuse events +- Remove completed events to free memory +- Vector clock monitors have O(n) checking cost + +### Visual Feedback + +```java +@Override +protected void onTimestampReached() { + VSInternalProcess internal = (VSInternalProcess) process; + + // Highlight process + internal.highlightOn(); + + // Log event + internal.log("Timestamp event: " + getAct |
