summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2023-06-19 21:01:14 +0300
committerPaul Buetow <paul@buetow.org>2023-06-19 21:01:14 +0300
commit1e970356767588ee309681cc7afbed798f108500 (patch)
treee683f0f137448c4bc9c90a62502621d1bedea103
parent8ab41dc0d90730009f5d547bbfaab93d5dd9496a (diff)
can write score file
-rw-r--r--integrationtests/gorum-uranus.json1
-rw-r--r--internal/quorum/quorum.go59
-rw-r--r--internal/quorum/quorum_test.go6
3 files changed, 60 insertions, 6 deletions
diff --git a/integrationtests/gorum-uranus.json b/integrationtests/gorum-uranus.json
index 3ef3419..a19d73c 100644
--- a/integrationtests/gorum-uranus.json
+++ b/integrationtests/gorum-uranus.json
@@ -5,6 +5,7 @@
"Address": ":3412",
"Nodes": [
"localhost:1234",
+ "localhost:2341",
"localhost:3412"
]
}
diff --git a/internal/quorum/quorum.go b/internal/quorum/quorum.go
index cb8f01e..19f4283 100644
--- a/internal/quorum/quorum.go
+++ b/internal/quorum/quorum.go
@@ -2,8 +2,12 @@ package quorum
import (
"context"
+ "fmt"
"log"
+ "os"
"sort"
+ "strconv"
+ "strings"
"time"
"codeberg.org/snonux/gorum/internal/config"
@@ -57,10 +61,12 @@ func (quo Quorum) Start(ctx context.Context) <-chan vote.Vote {
log.Println("quorum: changed my vote:", myVote)
ch <- myVote
}
- quo.score()
case <-ctx.Done():
return
}
+ if err := quo.persistScores(); err != nil {
+ log.Println("quorum:", err)
+ }
}
}()
@@ -77,7 +83,7 @@ func (quo Quorum) vote(v vote.Vote) {
quo.votes[v.FromID] = v
}
-func (quo Quorum) score() (scores []Score) {
+func (quo Quorum) scores() (scores []Score) {
scoreMap := make(map[string]int)
for _, vote := range quo.votes {
@@ -100,15 +106,62 @@ func (quo Quorum) score() (scores []Score) {
}
// Score tie, use node number.
+ // TODO: Don't do based on NodeNumber, but based on a priority
i_, _ := quo.conf.NodeNumber(scores[i].ID)
j_, _ := quo.conf.NodeNumber(scores[j].ID)
return i_ < j_
})
- log.Println("quorum: scores are ", scores)
return
}
+func (quo *Quorum) persistScores() error {
+ scores := quo.scores()
+ log.Println("quorum scores:", scores)
+
+ if _, err := os.Stat(quo.conf.StateDir); os.IsNotExist(err) {
+ if err := os.MkdirAll(quo.conf.StateDir, 0755); err != nil {
+ return err
+ }
+ }
+
+ stateFile := fmt.Sprintf("%s/scores", quo.conf.StateDir)
+ stateTmpFile := fmt.Sprintf("%s.tmp", stateFile)
+
+ fd, err := os.Create(stateTmpFile)
+ if err != nil {
+ return err
+ }
+ defer fd.Close()
+
+ var sb strings.Builder
+ sb.WriteString("current pos id score\n")
+
+ for i, score := range scores {
+ if score.ID == quo.conf.MyID {
+ sb.WriteString("yes")
+ } else {
+ sb.WriteString("no")
+ }
+ sb.WriteString(" ")
+ sb.WriteString(strconv.Itoa(i))
+ sb.WriteString(" ")
+ sb.WriteString(score.ID)
+ sb.WriteString(" ")
+ sb.WriteString(strconv.Itoa(score.Value))
+ sb.WriteString("\n")
+ }
+
+ if _, err := fd.WriteString(sb.String()); err != nil {
+ return err
+ }
+
+ if err := fd.Sync(); err != nil {
+ return err
+ }
+ return os.Rename(stateTmpFile, stateFile)
+}
+
func (quo *Quorum) makeMyVote() (vote.Vote, bool) {
newVote, err := quo.pruneVotes()
if err != nil {
diff --git a/internal/quorum/quorum_test.go b/internal/quorum/quorum_test.go
index 8f50493..17d9789 100644
--- a/internal/quorum/quorum_test.go
+++ b/internal/quorum/quorum_test.go
@@ -37,7 +37,7 @@ func TestScore(t *testing.T) {
vote4.ExpiresAt = inOneHour
quo.vote(vote4)
- scores := quo.score()
+ scores := quo.scores()
if len(scores) != 3 {
t.Errorf("Expected scores to be of length 3: %v", scores)
}
@@ -73,7 +73,7 @@ func TestTieScore(t *testing.T) {
)
addVotes(conf, quo)
- scores := quo.score()
+ scores := quo.scores()
if len(scores) != 3 {
t.Errorf("Expected scores to be of length 3: %v", scores)
@@ -96,7 +96,7 @@ func TestTieScore(t *testing.T) {
)
addVotes(conf, quo)
- scores := quo.score()
+ scores := quo.scores()
if len(scores) != 3 {
t.Errorf("Expected scores to be of length 3: %v", scores)