Skip to content

Instantly share code, notes, and snippets.

@SimonRichardson
Created February 12, 2020 12:42
Show Gist options
  • Save SimonRichardson/3329049f116f94fe7c7e4e27e3de63c0 to your computer and use it in GitHub Desktop.
Save SimonRichardson/3329049f116f94fe7c7e4e27e3de63c0 to your computer and use it in GitHub Desktop.
package main
import (
"bufio"
"fmt"
"io"
"log"
"os"
"gopkg.in/yaml.v2"
)
func main() {
files := os.Args[1:]
if len(files) == 0 {
log.Fatal("expected at least on file")
}
rules := []Rule{
NewRaftRule(),
}
for _, file := range files {
f, err := os.Open(file)
if err != nil {
log.Fatal(err)
}
row1, _, err := bufio.NewReader(f).ReadLine()
if err != nil {
log.Fatal(err)
}
_, err = f.Seek(int64(len(row1)), io.SeekStart)
if err != nil {
log.Fatal(err)
}
var report Report
if err := yaml.NewDecoder(f).Decode(&report); err != nil {
log.Fatal(err)
}
// TODO (pick a better name somehow - agent.name?)
name := report.Manifolds["agent"].Report.Agent
for _, rule := range rules {
rule.Run(name, report)
}
}
fmt.Println("Analysis of Engine Report:")
fmt.Println("")
for _, rule := range rules {
fmt.Println(rule.Summary())
fmt.Println("\t", rule.Analyse())
}
}
type Report struct {
Manifolds map[string]Worker `yaml:"manifolds"`
}
type Worker struct {
Inputs []string `yaml:"inputs"`
Report WorkerReport `yaml:"report"`
StartCount int `yaml:"start-count"`
Started string `yaml:"started"`
State string `yaml:"state"`
}
type WorkerReport struct {
Agent string `yaml:"agent"`
State string `yaml:"state"`
}
type Rule interface {
Run(string, Report)
Summary() string
Analyse() string
}
type RaftRule struct {
found map[string]bool
leaders map[string]bool
}
func NewRaftRule() *RaftRule {
return &RaftRule{
found: make(map[string]bool),
leaders: make(map[string]bool),
}
}
func (r *RaftRule) Run(name string, report Report) {
raft, ok := report.Manifolds["raft"]
if !ok {
r.found[name] = false
return
}
r.found[name] = true
r.leaders[name] = raft.Report.State == "Leader"
}
func (r *RaftRule) Summary() string {
return "Raft Leader:"
}
func (r *RaftRule) Analyse() string {
var leader bool
var ctrl string
for name, ldr := range r.leaders {
if leader && ldr {
// Two or more leaders
return "Two or leaders have been found in the files."
}
if ldr {
leader = true
ctrl = name
}
}
if !leader {
return fmt.Sprintf("There are no leaders found.")
}
return fmt.Sprintf("%s is the leader.", ctrl)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment