diff --git a/cmd/agent/main.go b/cmd/agent/main.go index 39fb0c6..71248f9 100644 --- a/cmd/agent/main.go +++ b/cmd/agent/main.go @@ -8,19 +8,19 @@ import ( "path/filepath" "time" - "github.com/golang/glog" "github.com/filmil/synod/internal/names" "github.com/filmil/synod/internal/paxos" "github.com/filmil/synod/internal/server" "github.com/filmil/synod/internal/state" paxosv1 "github.com/filmil/synod/proto/paxos/v1" + "github.com/golang/glog" ) var ( - stateDir = flag.String("state_dir", "", "Directory for state files (required)") - grpcAddr = flag.String("grpc_addr", ":50051", "gRPC address to listen on") - httpAddr = flag.String("http_addr", ":8080", "HTTP address to listen on") - peerAddr = flag.String("peer", "", "Address of an existing peer to join the cell") + stateDir = flag.String("state_dir", "", "Directory for state files (required)") + grpcAddr = flag.String("grpc_addr", ":50051", "gRPC address to listen on") + httpAddr = flag.String("http_addr", ":8080", "HTTP address to listen on") + peerAddr = flag.String("peer", "", "Address of an existing peer to join the cell") pingInterval = flag.Duration("ping_interval", 2*time.Minute, "Interval to ping peers") ) @@ -122,7 +122,7 @@ func main() { if err := store.AddMember(resp.AgentId, state.PeerInfo{GRPCAddr: *peerAddr, ShortName: "Unknown"}); err != nil { glog.Errorf("Failed to add join peer to membership: %v", err) } - + // Download the consensus value of the list of peers ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) kvResp, err := client.GetKVEntry(ctx, &paxosv1.GetKVEntryRequest{Key: "/_internal/peers"}) @@ -138,7 +138,7 @@ func main() { } cell.ApplyMembershipChange(kvResp.Value) } - + // After joining and getting the latest map, we must propose *ourselves* to the map! glog.Infof("Proposing newly joined node self to /_internal/peers") if err := cell.ProposeMembership(context.Background(), agentID, selfInfo); err != nil { @@ -176,7 +176,7 @@ func main() { }() glog.Infof("Synod agent is up and running") - + if err := <-errChan; err != nil { glog.Errorf("Server error: %v", err) os.Exit(1) diff --git a/internal/names/BUILD.bazel b/internal/names/BUILD.bazel index 713bc7d..5e6cf3c 100644 --- a/internal/names/BUILD.bazel +++ b/internal/names/BUILD.bazel @@ -1,13 +1,31 @@ -load("@rules_go//go:def.bzl", "go_library") +load("@rules_go//go:def.bzl", "go_binary", "go_library", "go_test") go_library( name = "names", - srcs = ["names.go"], + srcs = [ + "names.go", + ":names_data", + ], importpath = "github.com/filmil/synod/internal/names", visibility = ["//visibility:public"], - data = ["names.txt"], - deps = [ - "@com_github_golang_glog//:glog", - "@rules_go//go/runfiles:go_default_library", - ], +) + +go_test( + name = "names_test", + srcs = ["names_test.go"], + embed = [":names"], +) + +genrule( + name = "names_data", + srcs = ["//third_party/names:names.txt"], + outs = ["names_data.go"], + cmd = "$(location :gen) $< $@", + tools = [":gen"], +) + +go_binary( + name = "gen", + srcs = ["gen/gen.go"], + visibility = ["//visibility:private"], ) diff --git a/internal/names/gen/gen.go b/internal/names/gen/gen.go new file mode 100644 index 0000000..1a5496f --- /dev/null +++ b/internal/names/gen/gen.go @@ -0,0 +1,52 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strings" +) + +func main() { + if len(os.Args) != 3 { + fmt.Fprintf(os.Stderr, "Usage: %s \n", os.Args[0]) + os.Exit(1) + } + + inputFile := os.Args[1] + outputFile := os.Args[2] + + in, err := os.Open(inputFile) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to open input: %v\n", err) + os.Exit(1) + } + defer in.Close() + + out, err := os.Create(outputFile) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create output: %v\n", err) + os.Exit(1) + } + defer out.Close() + + fmt.Fprintln(out, "package names") + fmt.Fprintln(out, "") + fmt.Fprintln(out, "func init() {") + fmt.Fprintln(out, "\tloadedNames = []string{") + + scanner := bufio.NewScanner(in) + for scanner.Scan() { + name := strings.TrimSpace(scanner.Text()) + if name != "" { + fmt.Fprintf(out, "\t\t%q,\n", name) + } + } + if err := scanner.Err(); err != nil { + fmt.Fprintf(os.Stderr, "Error reading input: %v\n", err) + os.Exit(1) + } + + fmt.Fprintln(out, "\t}") + fmt.Fprintln(out, "}") +} diff --git a/internal/names/names.go b/internal/names/names.go index d259c68..999f271 100644 --- a/internal/names/names.go +++ b/internal/names/names.go @@ -1,41 +1,14 @@ package names import ( - "bufio" "math/rand" - "os" "time" - - "github.com/bazelbuild/rules_go/go/runfiles" - "github.com/golang/glog" ) var loadedNames []string func init() { rand.Seed(time.Now().UnixNano()) - - path, err := runfiles.Rlocation("_main/internal/names/names.txt") - if err != nil { - path, err = runfiles.Rlocation("synod/internal/names/names.txt") - } - - if err != nil { - glog.Errorf("Failed to resolve names.txt runfile: %v", err) - return - } - - file, err := os.Open(path) - if err != nil { - glog.Errorf("Failed to open names.txt: %v", err) - return - } - defer file.Close() - - scanner := bufio.NewScanner(file) - for scanner.Scan() { - loadedNames = append(loadedNames, scanner.Text()) - } } // Generate returns a random name from the pre-loaded list. diff --git a/internal/names/names_test.go b/internal/names/names_test.go new file mode 100644 index 0000000..17e42f2 --- /dev/null +++ b/internal/names/names_test.go @@ -0,0 +1,15 @@ +package names + +import ( + "testing" +) + +func TestGenerate(t *testing.T) { + if len(loadedNames) == 0 { + t.Fatal("loadedNames is empty") + } + name := Generate() + if name == "" || name == "Anonymous" { + t.Errorf("Generate() returned %q, expected a name from the list", name) + } +} diff --git a/third_party/names/BUILD.bazel b/third_party/names/BUILD.bazel new file mode 100644 index 0000000..f4ac0d0 --- /dev/null +++ b/third_party/names/BUILD.bazel @@ -0,0 +1 @@ +exports_files(["names.txt"]) diff --git a/third_party/names/LICENSE b/third_party/names/LICENSE new file mode 100644 index 0000000..f8e4415 --- /dev/null +++ b/third_party/names/LICENSE @@ -0,0 +1,4 @@ +Data from US Social Security Administration. +Source: https://www.ssa.gov/oact/babynames/limits.html + +The Social Security Administration (SSA) makes this information available to the public. As a product of a United States government agency, these datasets are generally considered to be in the public domain. diff --git a/internal/names/names.txt b/third_party/names/names.txt similarity index 100% rename from internal/names/names.txt rename to third_party/names/names.txt