func (s *RaftServer) doOrProxyCommandOnce(command raft.Command) (interface{}, error) { if s.raftServer.State() == raft.Leader { value, err := s.raftServer.Do(command) if err != nil { log.Error("Cannot run command %#v. %s", command, err) } return value, err } else { if leader, ok := s.leaderConnectString(); !ok { return nil, errors.New("Couldn't connect to the cluster leader...") } else { var b bytes.Buffer if err := json.NewEncoder(&b).Encode(command); err != nil { return nil, err } resp, err := http.Post(leader+"/process_command/"+command.CommandName(), "application/json", &b) if err != nil { return nil, err } defer resp.Body.Close() body, err2 := ioutil.ReadAll(resp.Body) if resp.StatusCode != 200 { return nil, errors.New(strings.TrimSpace(string(body))) } var js interface{} json.Unmarshal(body, &js) return js, err2 } } return nil, nil }
// SendCommand sends command to other peer and receives reply func (transporter *ZmqTransporter) SendCommand(peer string, command raft.Command) error { socket, err := transporter.getSocketFor(peer) if err != nil { return fmt.Errorf("unable to create socket for peer %s: %v", peer, err) } buf := new(bytes.Buffer) buf.WriteByte(requestCommand) encoder := json.NewEncoder(buf) encoder.Encode(command.CommandName()) encoder.Encode(command) _, err = socket.SendBytes(buf.Bytes(), 0) if err != nil { return fmt.Errorf("unable to send command %s to peer %s: %v", command.CommandName(), peer, err) } response, err := socket.RecvBytes(0) if err != nil { return fmt.Errorf("unable to receive %s response from peer %s: %v", command.CommandName(), peer, err) } var result interface{} err = json.Unmarshal(response, &result) if err != nil { return fmt.Errorf("unable to decode %s response from peer %s: %v", command.CommandName(), peer, err) } if result != nil { return fmt.Errorf("error response to command %s from peer %s: %v", command.CommandName(), peer, result) } return nil }
func SendCommandToServer(url string, command raft.Command) (interface{}, error) { var b bytes.Buffer if err := json.NewEncoder(&b).Encode(command); err != nil { return nil, err } resp, err := http.Post(url+"/process_command/"+command.CommandName(), "application/json", &b) if err != nil { return nil, err } defer resp.Body.Close() body, err2 := ioutil.ReadAll(resp.Body) if resp.StatusCode != 200 { return nil, errors.New(strings.TrimSpace(string(body))) } return body, err2 }