Пример #1
0
// This is the only user-facing function, and accordingly the body is
// a raw string rather than JSON.
func (s *Server) sqlHandler(w http.ResponseWriter, req *http.Request) {
	state := s.cluster.State()
	if state != "primary" {
		http.Error(w, "Only the primary can service queries, but this is a "+state, http.StatusBadRequest)
		return
	}

	query, err := ioutil.ReadAll(req.Body)
	if err != nil {
		log.Printf("Couldn't read body: %s", err)
		http.Error(w, err.Error(), http.StatusBadRequest)
	}

	log.Debugf("[%s] Received query: %#v", s.cluster.State(), string(query))
	resp, err := s.execute(query)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
	}

	r := &Replicate{
		Self:  s.cluster.self,
		Query: query,
	}
	for _, member := range s.cluster.members {
		b := util.JSONEncode(r)
		_, err := s.client.SafePost(member.ConnectionString, "/replicate", b)
		if err != nil {
			log.Printf("Couldn't replicate query to %v: %s", member, err)
		}
	}

	log.Debugf("[%s] Returning response to %#v: %#v", s.cluster.State(), string(query), string(resp))
	w.Write(resp)
}
Пример #2
0
// This is the only user-facing function, and accordingly the body is
// a raw string rather than JSON.
func (s *Server) sqlHandler(w http.ResponseWriter, req *http.Request) {
	query, err := ioutil.ReadAll(req.Body)
	if err != nil {
		log.Printf("Couldn't read body: %s", err)
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	log.Debugf("[%s] Received query: %#v", s.raftServer.State(), string(query))

	// Execute the command against the Raft server.
	leader := s.raftServer.Leader()
	for leader == "" {
		time.Sleep(50 * time.Millisecond)
		leader = s.raftServer.Leader()
	}
	if s.name != leader {
		my_partial_name := strings.TrimSuffix(strings.TrimPrefix(s.name, ".-"), ".sock")
		leader_partial_name := strings.TrimSuffix(strings.TrimPrefix(leader, ".-"), ".sock")
		redirect_url := "http://" + strings.Replace(req.Host, my_partial_name, leader_partial_name, -1) + "/forward?query=" + encodeQuery(query)
		log.Printf("Redirecting to %s", redirect_url)
		http.Redirect(w, req, redirect_url, 302)
		return
	}

	resp, err := s.raftServer.Do(NewSqlCommand(string(query)))
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	resp_frd := resp.([]byte)
	log.Debugf("[%s] Returning response to %#v: %#v", s.raftServer.State(), string(query), string(resp_frd))
	w.Write(resp_frd)
}
Пример #3
0
// This is the only user-facing function, and accordingly the body is
// a raw string rather than JSON.
func (s *Server) sqlHandler(w http.ResponseWriter, req *http.Request) {
	state := s.cluster.State()
	query, err := ioutil.ReadAll(req.Body)

	if state != "primary" {
		log.Printf("I AM NOT THE PRIMARY, NEED TO FORWARD THIS REQUEST TO MASTER")
		//cs, err := transport.Encode(primary)
		response, err := s.client.SafePost(s.cluster.primary.ConnectionString, "/sql", bytes.NewReader(query))
		if response == nil || err != nil {
			http.Error(w, "", http.StatusBadRequest)
			return
		} else {
			r, _ := ioutil.ReadAll(response)
			w.Write(r)
		}
		//http.Error(w, "Only the primary can service queries, but this is a "+state, http.StatusBadRequest)
		return
	}

	if err != nil {
		log.Printf("Couldn't read body: %s", err)
		http.Error(w, "", http.StatusBadRequest)
	}

	log.Debugf("[%s] Received query: %#v", s.cluster.State(), string(query))
	resp, err := s.execute(query)
	if err != nil {
		http.Error(w, "", http.StatusBadRequest)
	}

	//r := &Replicate{
	//Self:  s.cluster.self,
	//Query: query,
	//}
	//for _, member := range s.cluster.members {
	//b := util.JSONEncode(r)
	//_, err := s.client.SafePost(member.ConnectionString, "/replicate", b)
	//if err != nil {
	//log.Printf("Couldn't replicate query to %v: %s", member, err)
	//}
	//}

	log.Debugf("[%s] Returning response to %#v: %#v", s.cluster.State(), string(query), string(resp))
	w.Write(resp)
}
Пример #4
0
// This is the only user-facing function, and accordingly the body is
// a raw string rather than JSON.
func (s *Server) sqlHandler(w http.ResponseWriter, req *http.Request) {
	if s.block {
		time.Sleep(1000000 * time.Second)
	}

	query, err := ioutil.ReadAll(req.Body)
	if err != nil {
		log.Printf("Couldn't read body: %s", err)
		http.Error(w, err.Error(), http.StatusBadRequest)
	}

	if s.leader != s.listen {

		cs, errLeader := transport.Encode(s.leader)

		if errLeader != nil {
			http.Error(w, "Only the primary can service queries, but this is a secondary", http.StatusBadRequest)
			log.Printf("Leader ain't present?: %s", errLeader)
			return
		}

		//_, errLeaderHealthCheck := s.client.SafeGet(cs, "/healthcheck")

		//if errLeaderHealthCheck != nil {
		//    http.Error(w, "Primary is down", http.StatusBadRequest)
		//    return
		//}

		body, errLResp := s.client.SafePost(cs, "/sql", bytes.NewBufferString(string(query)))
		if errLResp != nil {
			s.block = true
			http.Error(w, "Can't forward request to primary, gotta block now", http.StatusBadRequest)
			return
			//	        log.Printf("Didn't get reply from leader: %s", errLResp)
		}

		formatted := fmt.Sprintf("%s", body)
		resp := []byte(formatted)

		w.Write(resp)
		return

	} else {

		log.Debugf("Primary Received query: %#v", string(query))
		resp, err := s.execute(query)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
		}

		w.Write(resp)
		return
	}
}
Пример #5
0
func (s *Server) forwardHandler(w http.ResponseWriter, req *http.Request) {
	query := req.URL.Query()
	encoded_query := query["query"][0]
	decoded_query, err := decodeQuery(encoded_query)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	resp, err := s.raftServer.Do(NewSqlCommand(string(decoded_query)))
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	resp_frd := resp.([]byte)
	log.Debugf("[%s] Returning response to %#v: %#v", s.raftServer.State(), string(decoded_query), string(resp_frd))
	w.Write(resp_frd)
}
Пример #6
0
// This is the only user-facing function, and accordingly the body is
// a raw string rather than JSON.
func (s *Server) sqlHandler(w http.ResponseWriter, req *http.Request) {
	// Read the value from the POST body.
	b, err := ioutil.ReadAll(req.Body)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	value := string(b)
	var output *sql.Output

	for {
		if s.raftServer.State() == raft.Candidate {
			time.Sleep(time.Millisecond * 100)
		} else {
			break
		}
	}
	/*


	   if s.raftServer.State() != raft.Leader {
	       cmd := &ExecCommand{
	           Data: *raft.NewExecuteCommand("", value),
	           Reply: make(chan *raft.ExecuteCommandReply),
	       }
	       s.execCommand <- cmd
	       reply := <-cmd.Reply
	       output = &reply.Output
	       err = reply.Error
	   } else {
	*/
	if s.raftServer.State() == raft.Leader {
		resp, err := s.raftServer.Do(raft.NewExecuteCommand(s.raftServer.Leader(), value))
		if err == nil {
			output = resp.(*sql.Output)
		}
		formatted := ""
		// Execute the command against the Raft server.
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			formatted = err.Error()
		} else {
			formatted = fmt.Sprintf("SequenceNumber: %d\n%s", output.SequenceNumber, output.Stdout)
		}
		log.Debugf("[%s] Returning response to %#v: %#v", s.raftServer.Leader(), value, formatted)
		w.Write([]byte(formatted))
	} else {
		/*
		   cmd := &ExecCommand{
		       Data: *raft.NewExecuteCommand("", value),
		       Reply: make(chan *raft.ExecuteCommandReply),
		   }
		   s.execCommand <- cmd
		   reply := <-cmd.Reply
		   output = &reply.Output
		   err = reply.Error
		   formatted := ""
		   // Execute the command against the Raft server.
		   if err != nil {
		       http.Error(w, err.Error(), http.StatusBadRequest)
		       formatted = err.Error()
		   } else {
		       formatted = fmt.Sprintf("SequenceNumber: %d\n%s", output.SequenceNumber, output.Stdout)
		   }
		   log.Debugf("[%s] Returning response to %#v: %#v", s.raftServer.Leader(), value, formatted)
		   w.Write([]byte(formatted))
		*/
		for {
			p, ok := s.raftServer.Peers()[s.raftServer.Leader()]
			if ok {
				r, e := s.client.SafePost(p.ConnectionString, "/sql", bytes.NewBuffer(b))
				if e == nil {
					rb, e := ioutil.ReadAll(r)
					if e == nil {
						w.Write(rb)
						return
					}
				}
			}
			time.Sleep(100 * time.Millisecond)
		}
	}
}