func main() { // Gather statistics about the data file. filesz, checksum, err := stat(*datafile) if err != nil { log.Fatal(err) } // Set up this process to be discovered. Choose a random port. discovery, port, err := newMulticastDiscovery(*host, *discoveryGroup, *discoveryLifetime) if err != nil { log.Fatal(err) } // Build a state machine arount the data file statistics. ID is the port. machine, err := newStateMachine(uint64(port), filesz, checksum, *maxmem) if err != nil { log.Fatal(err) } // Build a Raft server, applying into our state machine. ID is the port. raftServer := raft.NewServer(uint64(port), &bytes.Buffer{}, machine.Apply) // HTTP server, for Progol discovery/validation, and Raft communication. http.HandleFunc(progol.ValidationPath, okHandler) raft.HTTPTransport(http.DefaultServeMux, raftServer) go http.ListenAndServe(net.JoinHostPort(*host, fmt.Sprint(port)), nil) // When we discover new peers at the Progol level, // we'll want to propagate that topology to Raft. substrate := make(chan []progol.Peer) ready := make(chan struct{}) go propagate(substrate, raftServer, *minimum, ready) // Start a validator, to publish Progol peers to our propagator. validator := progol.NewValidator(discovery, *validationInterval) validator.Subscribe(substrate) defer validator.Unsubscribe(substrate) // Wait for some minimum number of nodes. <-ready // Then, start the Raft server. log.SetOutput(&bytes.Buffer{}) raftServer.Start() // After some random amount of time, make a claim time.Sleep(time.Duration(1000+rand.Intn(1000)) * time.Millisecond) raftServer.Command(machine.MakeClaim(), make(chan []byte, 1)) // Wait until our state machine reports the offset we own. offset, length := machine.Segment() // blocking // Process that segment output := process(*datafile, offset, length) fmt.Printf("%s\n", output) <-signalHandler() }
func start() { rand.Seed(42) // Construct the server s = raft.NewServer(uint64(*id), &bytes.Buffer{}, apply) // Expose the server using a HTTP transport raft.HTTPTransport(http.DefaultServeMux, s) http.HandleFunc("/response", response) serve := func() { err := http.ListenAndServe(*httpAddr, nil) if err != nil { panic(err) } else { log.Println("contd") } } go serve() time.Sleep(time.Second * 5) peers := mustNewPeers() // Set the initial server configuration s.SetConfiguration(peers...) // Start the server s.Start() fmt.Println("READY!") dn, _ := os.Open("/dev/null") log.SetOutput(dn) for { cmd := make(chan []byte) var bytz []byte buf := bytes.NewBuffer(bytz) enc := gob.NewEncoder(buf) err := enc.Encode(parseQuery()) if err != nil { panic(err) } if err := s.Command(buf.Bytes(), cmd); err != nil { panic(err) } fmt.Println(string(<-cmd)) } }
func ExampleNewServer_hTTP() { // A no-op ApplyFunc a := func(uint64, []byte) []byte { return []byte{} } // Helper function to parse URLs mustParseURL := func(rawurl string) *url.URL { u, err := url.Parse(rawurl) if err != nil { panic(err) } u.Path = "" return u } // Helper function to construct HTTP Peers mustNewHTTPPeer := func(u *url.URL) raft.Peer { p, err := raft.NewHTTPPeer(u) if err != nil { panic(err) } return p } // Construct the server s := raft.NewServer(1, &bytes.Buffer{}, a) // Expose the server using a HTTP transport raft.HTTPTransport(http.DefaultServeMux, s) go http.ListenAndServe(":8080", nil) // Set the initial server configuration s.SetConfiguration( mustNewHTTPPeer(mustParseURL("http://127.0.0.1:8080")), // this server mustNewHTTPPeer(mustParseURL("http://10.1.1.11:8080")), mustNewHTTPPeer(mustParseURL("http://10.1.1.12:8080")), mustNewHTTPPeer(mustParseURL("http://10.1.1.13:8080")), mustNewHTTPPeer(mustParseURL("http://10.1.1.14:8080")), ) // Start the server s.Start() }