Пример #1
0
// logSnapshot logs about the snapshot that was taken.
func (s *Server) logSnapshot(err error, currentIndex, count uint64) {
	info := fmt.Sprintf("%s: snapshot of %d events at index %d", s.connectionString(), count, currentIndex)
	if err != nil {
		log.Infof("%s attempted and failed: %v", info, err)
	} else {
		log.Infof("%s completed", info)
	}
}
Пример #2
0
// Join joins to the leader of an existing cluster.
func (s *Server) Join(leader string) error {
	command := &raft.DefaultJoinCommand{
		Name:             s.raftServer.Name(),
		ConnectionString: s.connectionString(),
	}

	var b bytes.Buffer
	if err := json.NewEncoder(&b).Encode(command); err != nil {
		return nil
	}

	resp, err := http.Post(fmt.Sprintf("http://%s/join", leader), "application/json", &b)
	if err != nil {
		return err
	}
	defer func() {
		_ = resp.Body.Close()
	}()

	// Look for redirect.
	if resp.StatusCode == http.StatusTemporaryRedirect {
		leader := resp.Header.Get("Location")
		if leader == "" {
			return errors.New("Redirect requested, but no location header supplied")
		}
		u, err := url.Parse(leader)
		if err != nil {
			return errors.New("Failed to parse redirect location")
		}
		log.Infof("Redirecting to leader at %s", u.Host)
		return s.Join(u.Host)
	}

	return nil
}
Пример #3
0
func main() {
	flag.Parse()

	// Set up profiling, if requested.
	if cpuprofile != "" {
		log.Info("Profiling enabled")
		f, err := os.Create(cpuprofile)
		if err != nil {
			log.Errorf("Unable to create path: %s", err.Error())
		}
		defer closeFile(f)

		err = pprof.StartCPUProfile(f)
		if err != nil {
			log.Errorf("Unable to start CPU Profile: %s", err.Error())
		}

		defer pprof.StopCPUProfile()
	}

	// Set logging
	log.SetLevel(logLevel)
	if logFile != "stdout" {
		f := createFile(logFile)
		defer closeFile(f)

		log.Infof("Redirecting logging to %s", logFile)
		log.SetOutput(f)
	}

	// Set the data directory.
	if flag.NArg() == 0 {
		flag.Usage()
		println("Data path argument required")
		log.Error("No data path supplied -- aborting")
		os.Exit(1)
	}

	dataPath := flag.Arg(0)
	createDir(dataPath)

	s := server.NewServer(dataPath, dbfile, snapAfter, host, port)
	go func() {
		log.Error(s.ListenAndServe(join).Error())
	}()

	if !disableReporting {
		reportLaunch()
	}

	terminate := make(chan os.Signal, 1)
	signal.Notify(terminate, os.Interrupt)
	<-terminate
	log.Info("rqlite server stopped")
}
Пример #4
0
// ListenAndServe starts the server.
func (s *Server) ListenAndServe(leader string) error {
	var err error

	log.Infof("Initializing Raft Server: %s", s.path)

	// Initialize and start Raft server.
	transporter := raft.NewHTTPTransporter("/raft", 200*time.Millisecond)
	stateMachine := NewDbStateMachine(s.dbPath)
	s.raftServer, err = raft.NewServer(s.name, s.path, transporter, stateMachine, s.db, "")
	if err != nil {
		log.Errorf("Failed to create new Raft server: %s", err.Error())
		return err
	}

	log.Info("Loading latest snapshot, if any, from disk")
	if err := s.raftServer.LoadSnapshot(); err != nil && os.IsNotExist(err) {
		log.Info("no snapshot found")
	} else if err != nil {
		log.Errorf("Error loading snapshot: %s", err.Error())
	}

	transporter.Install(s.raftServer, s)
	if err := s.raftServer.Start(); err != nil {
		log.Errorf("Error starting raft server: %s", err.Error())
	}

	if leader != "" {
		// Join to leader if specified.

		log.Infof("Attempting to join leader at %s", leader)

		if !s.raftServer.IsLogEmpty() {
			log.Error("Cannot join with an existing log")
			return errors.New("Cannot join with an existing log")
		}
		if err := s.Join(leader); err != nil {
			log.Errorf("Failed to join leader: %s", err.Error())
			return err
		}

	} else if s.raftServer.IsLogEmpty() {
		// Initialize the server by joining itself.

		log.Info("Initializing new cluster")

		_, err := s.raftServer.Do(&raft.DefaultJoinCommand{
			Name:             s.raftServer.Name(),
			ConnectionString: s.connectionString(),
		})
		if err != nil {
			log.Errorf("Failed to join to self: %s", err.Error())
		}

	} else {
		log.Info("Recovered from log")
	}

	log.Info("Initializing HTTP server")

	// Initialize and start HTTP server.
	s.httpServer = &http.Server{
		Addr:    fmt.Sprintf(":%d", s.port),
		Handler: s.router,
	}

	s.router.HandleFunc("/statistics", s.serveStatistics).Methods("GET")
	s.router.HandleFunc("/diagnostics", s.serveDiagnostics).Methods("GET")
	s.router.HandleFunc("/raft", s.serveRaftInfo).Methods("GET")
	s.router.HandleFunc("/db", s.readHandler).Methods("GET")
	s.router.HandleFunc("/db", s.writeHandler).Methods("POST")
	s.router.HandleFunc("/join", s.joinHandler).Methods("POST")

	log.Infof("Listening at %s", s.connectionString())

	return s.httpServer.ListenAndServe()
}