You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Three armies, each led by a general, plan to attack a fortified city. The armies may arrive at different times to surround the city, and none of the generals can be certain whether all the armies will arrive at all. Consequently, they have not appointed a single leader.
156
+
For the attack to succeed, at least two armies must strike simultaneously. Therefore, the generals need to coordinate and agree on a precise time to launch the attack.
157
+
To achieve this, they decide to use a simplified version of the Raft algorithm.
Copy file name to clipboardExpand all lines: docs/exercises/Exercise8.md
+23-20Lines changed: 23 additions & 20 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,7 +16,7 @@ Three armies, each led by a general, plan to attack a fortified city. The armies
16
16
For the attack to succeed, at least two armies must strike simultaneously. Therefore, the generals need to coordinate and agree on a precise time to launch the attack.
17
17
To achieve this, they decide to use a simplified version of the Raft algorithm.
18
18
19
-
In the following, we will represent the armies as nodes and facilitate communication between them using REST.
19
+
In the following, we will represent the armies as nodes and facilitate communication between them using REST APIs.
20
20
21
21
### Define list of servers (nodes)
22
22
@@ -35,7 +35,7 @@ var nodePortList = []string{
35
35
On start of the program the node id should be read as argument from the console.
36
36
```raft --node 0```
37
37
38
-
Use the `flag` package to read the arguments.
38
+
Use the `flag`[package](https://pkg.go.dev/flag) to read the arguments.
39
39
40
40
### State
41
41
@@ -45,47 +45,50 @@ Define an [enum](https://gobyexample.com/enums] containin) for the node state
45
45
* Candidate
46
46
* Leader
47
47
48
-
Implement the [stringer](https://go.dev/tour/methods/17) interface for the enum.
49
48
Write a function to switch the state of the node.
50
49
It should apply the following rules, otherwise stop the program.
51
50
52
51
* A leader can never change
53
-
* A candidate can only change to leader or follower
54
-
* A follower can only change to candidate
52
+
* A candidate can only change to a leader or follower
53
+
* A follower can only change to a candidate
55
54
56
-
For now, node 0 start as the leader, the others as followers.
55
+
For now, node 0 starts as a leader, the others as followers.
57
56
58
57
### Attack Endpoint
59
58
60
-
Implement an "attack" endpoint and start an asynchronous running server on the port defined by the port list.
61
-
The attack endpoint receives the time of the attack as string, prints the attack time on screen and returns a 200 status code.
59
+
Implement an "attack" endpoint and start the server on the port defined by the port list.
60
+
The "attack" endpoint uses the REST Method POST, receives the time of the attack as string, prints the attack time on screen and returns a 200 status code.
62
61
You can test it via curl, httpie or wget.
63
62
64
63
```
65
64
curl -X POST http://localhost:10000/attack -d "midnight"
66
65
```
67
66
68
-
After a few seconds (e.g. 30 seconds) the leader should send an attack request to the other nodes to attack at the same time.
67
+
If the node is the leader: After a few seconds (e.g. 30 seconds) the leader should send an attack request to the other nodes to attack at the same time.
69
68
Only when the leader receives an OK response from at least one other node, the attack is successful.
70
69
71
-
Optional task: You can send a commit message to the followers to confirm the attack.
70
+
Optional task: You can send a commit message to the followers to confirm the attack. You just have to implement a commit endpoint.
72
71
73
-
### Heartbeat Endpoint
72
+
### Simplified Heartbeat Endpoint
74
73
75
-
Implement the heartbeat mechanism.
76
-
Implement a heartbeat endpoint. It should just return a 200 status code.
77
-
Only the leader should send a heartbeat to the other nodes in intervals of 1 second.
74
+
Implement the heartbeat mechanism. Implement a heartbeat endpoint via a GET method. It should just return a 200 status code and turn the node into a follower.
75
+
The leader node should send a heartbeat to the other nodes in intervals of 1 second.
76
+
77
+
### Simplified Vote Endpoint
78
+
79
+
Implement a vote endpoint.
80
+
The vote endpoint uses the REST Method GET.
81
+
If the node is the leader, it should return "no" to the other nodes, otherwise "yes" and turn into a "follower".
78
82
79
83
### Simplified Leader Election
80
84
81
-
From now on all nodes start from the follower state. No one is the leader
85
+
From now on all nodes start from the follower state. No one is the leader.
82
86
83
-
- The nodes wait for heartbeats from the leader. E.g. for two seconds.
87
+
- The nodes wait for heartbeats from the leader. E.g. for two seconds.(Example via the time.After function: [heartbeat.go](../../src/distributed/byzantine/heartbeat.go))
84
88
- Because there is no leader, the nodes become candidates and start an election.
85
-
- The nodes wait for a random time between 1 and 5 seconds and start a voting process.
86
-
- for the voting they send a request to all other nodes.
87
-
- The nodes vote for the candidate and become followers.
88
-
- If an heartbeat is received, the nodes become followers as well and the voting stops.
89
+
- The nodes wait for a random time between 1 and 3 seconds and start a voting process.
90
+
- For the voting they send a request to all other nodes to the voting endpoint.
91
+
- If they receive a majority of "yes" votes, they become the leader and start the heartbeats.
0 commit comments