1
0
Fork 0

Tighten up server's use of WriteCommand

master
Philip O'Toole 10 years ago
parent 2a43c5b531
commit 06ccc6637e

@ -22,6 +22,30 @@ import (
log "code.google.com/p/log4go" log "code.google.com/p/log4go"
) )
type FailedSqlStmt struct {
Sql string `json:"sql"`
Error string `json:"error"`
}
type WriteResponse struct {
Time string `json:"time"`
Failures []FailedSqlStmt `json:"failures"`
}
// The raftd server is a combination of the Raft server and an HTTP
// server which acts as the transport.
type Server struct {
name string
host string
port int
path string
router *mux.Router
raftServer raft.Server
httpServer *http.Server
db *db.DB
mutex sync.RWMutex
}
// queryParam returns whether the given query param is set to true. // queryParam returns whether the given query param is set to true.
func queryParam(req *http.Request, param string) (bool, error) { func queryParam(req *http.Request, param string) (bool, error) {
err := req.ParseForm() err := req.ParseForm()
@ -45,26 +69,6 @@ func isTransaction(req *http.Request) (bool, error) {
return queryParam(req, "transaction") return queryParam(req, "transaction")
} }
type WriteResponse struct {
Time string
Success int
Fail int
}
// The raftd server is a combination of the Raft server and an HTTP
// server which acts as the transport.
type Server struct {
name string
host string
port int
path string
router *mux.Router
raftServer raft.Server
httpServer *http.Server
db *db.DB
mutex sync.RWMutex
}
// Creates a new server. // Creates a new server.
func New(dataDir string, dbfile string, host string, port int) *Server { func New(dataDir string, dbfile string, host string, port int) *Server {
s := &Server{ s := &Server{
@ -226,8 +230,7 @@ func (s *Server) readHandler(w http.ResponseWriter, req *http.Request) {
func (s *Server) writeHandler(w http.ResponseWriter, req *http.Request) { func (s *Server) writeHandler(w http.ResponseWriter, req *http.Request) {
log.Trace("writeHandler for URL: %s", req.URL) log.Trace("writeHandler for URL: %s", req.URL)
var nSuccess int var failures = make([]FailedSqlStmt, 0)
var nFail int
var startTime time.Time var startTime time.Time
// Read the value from the POST body. // Read the value from the POST body.
@ -242,40 +245,35 @@ func (s *Server) writeHandler(w http.ResponseWriter, req *http.Request) {
stmts = stmts[:len(stmts)-1] stmts = stmts[:len(stmts)-1]
} }
// Execute the command against the Raft server. log.Trace("Execute statement contains %d commands", len(stmts))
startTime = time.Now() if len(stmts) == 0 {
switch {
case len(stmts) == 0:
log.Trace("No database execute commands supplied") log.Trace("No database execute commands supplied")
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
case len(stmts) == 1:
log.Trace("Single statment, implicit transaction")
_, err = s.raftServer.Do(command.NewWriteCommand(stmts[0]))
if err != nil {
nFail++
} else {
nSuccess++
} }
case len(stmts) > 1:
log.Trace("Multistatement, transaction possible") startTime = time.Now()
transaction, _ := isTransaction(req) transaction, _ := isTransaction(req)
if transaction { if transaction {
log.Trace("Transaction requested") log.Trace("Transaction requested")
_, err = s.raftServer.Do(command.NewTransactionWriteCommandSet(stmts)) _, err = s.raftServer.Do(command.NewTransactionWriteCommandSet(stmts))
if err != nil { if err != nil {
nFail++ failures = append(failures, FailedSqlStmt{stmts[0], err.Error()})
} else { log.Trace("Transaction failed: %s", err.Error())
nSuccess++
} }
} else { } else {
log.Trace("No transaction requested") log.Trace("No transaction requested")
// Do each individually, returning JSON respoonse for i := range stmts {
_, err = s.raftServer.Do(command.NewWriteCommand(stmts[i]))
if err != nil {
log.Trace("Execute statement %s failed: %s", stmts[i], err.Error())
failures = append(failures, FailedSqlStmt{stmts[i], err.Error()})
}
} }
} }
duration := time.Since(startTime) duration := time.Since(startTime)
wr := WriteResponse{Time: duration.String(), Success: nSuccess, Fail: nFail} wr := WriteResponse{Time: duration.String(), Failures: failures}
pretty, _ := isPretty(req) pretty, _ := isPretty(req)
if pretty { if pretty {
b, err = json.MarshalIndent(wr, "", " ") b, err = json.MarshalIndent(wr, "", " ")

Loading…
Cancel
Save