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 package org.eclipse.jgit.internal.ketch;
45
46 import static org.eclipse.jgit.internal.ketch.KetchConstants.TERM;
47
48 import java.io.IOException;
49 import java.util.List;
50
51 import org.eclipse.jgit.lib.CommitBuilder;
52 import org.eclipse.jgit.lib.ObjectId;
53 import org.eclipse.jgit.lib.ObjectInserter;
54 import org.eclipse.jgit.lib.Repository;
55 import org.eclipse.jgit.lib.TreeFormatter;
56 import org.eclipse.jgit.revwalk.RevCommit;
57 import org.eclipse.jgit.revwalk.RevWalk;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61
62
63
64
65 class ElectionRound extends Round {
66 private static final Logger log = LoggerFactory.getLogger(ElectionRound.class);
67
68 private long term;
69
70 ElectionRound(KetchLeader leader, LogIndex head) {
71 super(leader, head);
72 }
73
74 @Override
75 void start() throws IOException {
76 ObjectId id;
77 try (Repository git = leader.openRepository();
78 ObjectInserter inserter = git.newObjectInserter()) {
79 id = bumpTerm(git, inserter);
80 inserter.flush();
81 }
82 runAsync(id);
83 }
84
85 @Override
86 void success() {
87
88 }
89
90 long getTerm() {
91 return term;
92 }
93
94 private ObjectId bumpTerm(Repository git, ObjectInserter inserter)
95 throws IOException {
96 CommitBuilder b = new CommitBuilder();
97 if (!ObjectId.zeroId().equals(acceptedOldIndex)) {
98 try (RevWalk rw = new RevWalk(git)) {
99 RevCommit c = rw.parseCommit(acceptedOldIndex);
100 b.setTreeId(c.getTree());
101 b.setParentId(acceptedOldIndex);
102 term = parseTerm(c.getFooterLines(TERM)) + 1;
103 }
104 } else {
105 term = 1;
106 b.setTreeId(inserter.insert(new TreeFormatter()));
107 }
108
109 StringBuilder msg = new StringBuilder();
110 msg.append(KetchConstants.TERM.getName())
111 .append(": ")
112 .append(term);
113
114 String tag = leader.getSystem().newLeaderTag();
115 if (tag != null && !tag.isEmpty()) {
116 msg.append(' ').append(tag);
117 }
118
119 b.setAuthor(leader.getSystem().newCommitter());
120 b.setCommitter(b.getAuthor());
121 b.setMessage(msg.toString());
122
123 if (log.isDebugEnabled()) {
124 log.debug("Trying to elect myself " + b.getMessage());
125 }
126 return inserter.insert(b);
127 }
128
129 private static long parseTerm(List<String> footer) {
130 if (footer.isEmpty()) {
131 return 0;
132 }
133
134 String s = footer.get(0);
135 int p = s.indexOf(' ');
136 if (p > 0) {
137 s = s.substring(0, p);
138 }
139 return Long.parseLong(s, 10);
140 }
141 }