summaryrefslogtreecommitdiff
path: root/src/main/java/examples/CreateWorkingRaftSimulation.java
blob: 0bc5df40a80d1c52800f5e9cc7444e6063a8ecd7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package examples;

import simulator.*;
import core.*;
import prefs.*;
import events.*;
import events.internal.*;
import events.implementations.*;
import serialize.VSSerialize;
import java.io.*;
import java.lang.reflect.*;

/**
 * Creates a working Raft simulation by properly setting up the event queue
 * and ensuring protocols are activated through the normal event system.
 */
public class CreateWorkingRaftSimulation {
    
    private static final String RAFT_PROTOCOL = "protocols.implementations.VSRaftProtocol";
    
    public static void main(String[] args) throws Exception {
        System.out.println("=== Creating Working Raft Simulation ===\n");
        
        // Initialize
        VSDefaultPrefs prefs = new VSDefaultPrefs();
        prefs.fillWithDefaults();
        VSRegisteredEvents.init(prefs);
        
        // Create simulator with frame
        VSSimulatorFrame frame = new VSSimulatorFrame(prefs, null);
        VSSimulator simulator = new VSSimulator(prefs, frame);
        frame.addSimulator(simulator);
        
        // Access visualization
        Field vizField = VSSimulator.class.getDeclaredField("simulatorVisualization");
        vizField.setAccessible(true);
        VSSimulatorVisualization viz = (VSSimulatorVisualization) vizField.get(simulator);
        
        // Add 5 processes (3 servers + 2 clients)
        Method addProcessMethod = VSSimulatorVisualization.class.getDeclaredMethod("addProcess");
        addProcessMethod.setAccessible(true);
        System.out.println("Adding 5 processes...");
        for (int i = 0; i < 5; i++) {
            addProcessMethod.invoke(viz);
        }
        
        VSTaskManager taskManager = viz.getTaskManager();
        
        // Schedule Raft server activations at time 0
        System.out.println("\nScheduling Raft server activations:");
        for (int i = 0; i < 3; i++) {
            VSProtocolEvent serverEvent = new VSProtocolEvent();
            serverEvent.setProtocolClassname(RAFT_PROTOCOL);
            serverEvent.isClientProtocol(false); // Server mode
            serverEvent.isProtocolActivation(true); // This is an activation
            
            VSTask task = new VSTask(0, viz.getProcess(i), serverEvent, false);
            taskManager.addTask(task);
            System.out.println("  - Server " + i + " activation scheduled at time 0");
        }
        
        // Schedule Raft client activations with slight delay
        System.out.println("\nScheduling Raft client activations:");
        for (int i = 3; i < 5; i++) {
            VSProtocolEvent clientEvent = new VSProtocolEvent();
            clientEvent.setProtocolClassname(RAFT_PROTOCOL);
            clientEvent.isClientProtocol(true); // Client mode
            clientEvent.isProtocolActivation(true); // This is an activation
            
            // Start clients after servers have initialized
            long startTime = 500 + (i - 3) * 200;
            VSTask task = new VSTask(startTime, viz.getProcess(i), clientEvent, false);
            taskManager.addTask(task);
            System.out.println("  - Client " + (i-3) + " activation scheduled at time " + startTime);
        }
        
        // Add some interesting events
        System.out.println("\nAdding crash/recovery events:");
        
        // Process 0 crashes at time 2000 and recovers at 3000
        VSProcessCrashEvent crash1 = new VSProcessCrashEvent();
        taskManager.addTask(new VSTask(2000, viz.getProcess(0), crash1, false));
        System.out.println("  - Server 0 crash scheduled at time 2000");
        
        VSProcessRecoverEvent recover1 = new VSProcessRecoverEvent();
        taskManager.addTask(new VSTask(3000, viz.getProcess(0), recover1, false));
        System.out.println("  - Server 0 recovery scheduled at time 3000");
        
        // Process 1 crashes at time 4000 and recovers at 5000
        VSProcessCrashEvent crash2 = new VSProcessCrashEvent();
        taskManager.addTask(new VSTask(4000, viz.getProcess(1), crash2, false));
        System.out.println("  - Server 1 crash scheduled at time 4000");
        
        VSProcessRecoverEvent recover2 = new VSProcessRecoverEvent();
        taskManager.addTask(new VSTask(5000, viz.getProcess(1), recover2, false));
        System.out.println("  - Server 1 recovery scheduled at time 5000");
        
        // Save simulation
        File outputFile = new File("saved-simulations/raft-working.dat");
        outputFile.getParentFile().mkdirs();
        
        System.out.println("\nSaving simulation...");
        VSSerialize serialize = new VSSerialize();
        serialize.saveSimulator(outputFile.getAbsolutePath(), simulator);
        
        frame.dispose();
        
        System.out.println("\n✓ Simulation saved to: " + outputFile.getAbsolutePath());
        
        // Create instruction file
        File instructionFile = new File("saved-simulations/README-raft.txt");
        try (PrintWriter writer = new PrintWriter(instructionFile)) {
            writer.println("RAFT CONSENSUS SIMULATION");
            writer.println("========================");
            writer.println();
            writer.println("This directory contains Raft consensus protocol simulations:");
            writer.println();
            writer.println("1. raft-working.dat - Full working simulation with:");
            writer.println("   - 3 Raft servers (processes 0-2)");
            writer.println("   - 2 Raft clients (processes 3-4)");
            writer.println("   - Server crash/recovery events");
            writer.println();
            writer.println("To run the simulation:");
            writer.println("1. java -jar target/ds-sim-1.0.1-SNAPSHOT.jar");
            writer.println("2. File → Open → saved-simulations/raft-working.dat");
            writer.println("3. Click Run (▶) button");
            writer.println();
            writer.println("What to look for:");
            writer.println("- Leader election (REQUEST_VOTE messages)");
            writer.println("- Heartbeats from leader (APPEND_ENTRIES)");
            writer.println("- Client requests and responses");
            writer.println("- Re-election when servers crash");
            writer.println();
            writer.println("Timeline:");
            writer.println("- Time 0: Servers start, begin leader election");
            writer.println("- Time 500-700: Clients start");
            writer.println("- Time 2000: Server 0 crashes");
            writer.println("- Time 3000: Server 0 recovers");
            writer.println("- Time 4000: Server 1 crashes");
            writer.println("- Time 5000: Server 1 recovers");
        }
        
        System.out.println("✓ Instructions saved to: " + instructionFile.getAbsolutePath());
        
        System.out.println("\n=== Success! ===");
        System.out.println("\nThe Raft simulation has been created with the following setup:");
        System.out.println("- 3 servers implementing Raft consensus");
        System.out.println("- 2 clients that will send requests");
        System.out.println("- Crash/recovery events to test fault tolerance");
        System.out.println("\nRun the simulator and load the file to see it in action!");
    }
}