migrate adhoc string r/w functions to bufio, get communication reliable

This commit is contained in:
Dan Ballard 2015-04-19 21:03:54 -07:00
parent 362474421d
commit 543d4c05d3
8 changed files with 67 additions and 82 deletions

View File

@ -7,6 +7,7 @@ import (
"net" "net"
"os" "os"
"strings" "strings"
"bufio"
// "os/exec" // "os/exec"
// "time" // "time"
) )
@ -49,22 +50,23 @@ var poolCmd = &warren.Command{
func warrendRun(cmd *warren.Command, args ...string) { func warrendRun(cmd *warren.Command, args ...string) {
s, err := net.Dial(warren.CmdSockType, warren.CmdSockAddr) sock, err := net.Dial(warren.CmdSockType, warren.CmdSockAddr)
if s != nil { if sock != nil {
defer s.Close() defer sock.Close()
} }
if err != nil { if err != nil {
log.Fatal("Error connecting to warrend:", err) log.Fatal("Error connecting to warrend:", err)
} }
dir, _ := os.Getwd() dir, _ := os.Getwd()
// pwd|arg1 arg2 arg3 .... // pwd|arg1 arg2 arg3 ....
warren.WriteStringz(s, dir+"/|"+cmd.Name+"|"+strings.Join(args, "|")) writer := bufio.NewWriter(sock)
writer.WriteString(dir+"/|"+cmd.Name+"|"+strings.Join(args, "|") +"\n")
resp, err := warren.ReadStringz(s) writer.Flush()
reader := bufio.NewReader(sock)
if err != nil {
log.Fatal(err)
}
if resp, err := reader.ReadString(0); err == nil {
fmt.Println(resp) fmt.Println(resp)
} else {
fmt.Println("not ok")
}
} }

View File

@ -3,7 +3,9 @@ package main
import ( import (
"github.com/dballard/warren/cmd/warrend/conf" "github.com/dballard/warren/cmd/warrend/conf"
"github.com/dballard/warren/lib/warren" "github.com/dballard/warren/lib/warren"
"net" "strconv"
"bufio"
"fmt"
) )
var listUsage = ` var listUsage = `
@ -19,16 +21,16 @@ var listCmd = &SockCommand{
Run: listRun, Run: listRun,
} }
func listRun(cmd *SockCommand, c net.Conn, path string, args ...string) { func listRun(cmd *SockCommand, writer *bufio.Writer, path string, args ...string) {
if len(args) > 0 && args[0] == "help" { if len(args) > 0 && args[0] == "help" {
warren.WriteStringz(c, cmd.Usage) writer.WriteString(cmd.Usage)
return return
} }
warren.WriteStringz(c, "List\n") writer.WriteString("List\n")
fmt.Print("List\n")
for n, p := range conf.GetConf().Deployments { for name, dep := range conf.GetConf().Deployments {
warren.WriteStringz(c, n+": "+p+"\n") writer.WriteString(name+" (ports " + strconv.Itoa(dep.Pool.Low) +":"+strconv.Itoa(dep.Pool.High)+") : "+dep.Path+"\n")
fmt.Print(name+" (ports " + strconv.Itoa(dep.Pool.Low) +":"+strconv.Itoa(dep.Pool.High)+") : "+dep.Path+"\n")
} }
} }

View File

@ -3,7 +3,7 @@ package main
import ( import (
//"github.com/dballard/warren/cmd/warrend/conf" //"github.com/dballard/warren/cmd/warrend/conf"
"github.com/dballard/warren/lib/warren" "github.com/dballard/warren/lib/warren"
"net" "bufio"
"strings" "strings"
) )
@ -22,21 +22,21 @@ var poolCmd = &SockCommand{
// pool [name] -- get // pool [name] -- get
// pool [name] [low] [high] -- set // pool [name] [low] [high] -- set
func poolRun(cmd *SockCommand, c net.Conn, path string, args ...string) { func poolRun(cmd *SockCommand, writer *bufio.Writer, path string, args ...string) {
if len(args) > 0 && args[0] == "help" { if len(args) > 0 && args[0] == "help" {
warren.WriteStringz(c, cmd.Usage) writer.WriteString(cmd.Usage)
return return
} }
// GET // GET
if len(args) == 1 { if len(args) == 1 {
warren.WriteStringz(c, "Pool GET " + strings.Join(args, ", ") + "\n") writer.WriteString("Pool GET " + strings.Join(args, ", ") + "\n")
return return
} }
if len(args) == 3 { if len(args) == 3 {
warren.WriteStringz(c, "Pool SET\n") writer.WriteString("Pool SET\n")
return return
} }
warren.WriteStringz(c, cmd.Usage) writer.WriteString(cmd.Usage)
return return
} }

View File

@ -3,7 +3,7 @@ package main
import ( import (
"github.com/dballard/warren/cmd/warrend/conf" "github.com/dballard/warren/cmd/warrend/conf"
"github.com/dballard/warren/lib/warren" "github.com/dballard/warren/lib/warren"
"net" "bufio"
"strings" "strings"
) )
@ -33,9 +33,9 @@ var unregCmd = &SockCommand{
} }
// reg path [nickname] // reg path [nickname]
func regRun(cmd *SockCommand, c net.Conn, path string, args ...string) { func regRun(cmd *SockCommand, writer *bufio.Writer, path string, args ...string) {
if (len(args) > 0 && args[0] == "help") || len(args) < 1 { if len(args) == 0 || args[0] == "" || (len(args) > 0 && args[0] == "help") {
warren.WriteStringz(c, cmd.Usage) writer.WriteString(cmd.Usage)
return return
} }
@ -58,18 +58,18 @@ func regRun(cmd *SockCommand, c net.Conn, path string, args ...string) {
err := d.Call() err := d.Call()
if err != nil { if err != nil {
warren.WriteStringz(c, "ERROR: "+err.Error()) writer.WriteString("ERROR: "+err.Error())
return return
} }
warren.WriteStringz(c, "Registered deployment "+d.Args["name"]+ " at "+d.Args["path"]) writer.WriteString("Registered deployment "+d.Args["name"]+ " at "+d.Args["path"])
} }
// unreg path // unreg path
// unreg nick // unreg nick
func unregRun(cmd *SockCommand, c net.Conn, path string, args ...string) { func unregRun(cmd *SockCommand, writer *bufio.Writer, path string, args ...string) {
if (len(args) > 0 && args[0] == "help") || len(args) < 1 { if (len(args) > 0 && args[0] == "help") || len(args) < 1 {
warren.WriteStringz(c, cmd.Usage) writer.WriteString(cmd.Usage)
return return
} }
@ -78,10 +78,10 @@ func unregRun(cmd *SockCommand, c net.Conn, path string, args ...string) {
d.Args["path"] = path d.Args["path"] = path
err := d.Call() err := d.Call()
if err != nil { if err != nil {
warren.WriteStringz(c, "ERROR: " + err.Error()) writer.WriteString("ERROR: " + err.Error())
return return
} }
warren.WriteStringz(c, "Unregistered deployment " + args[0]) writer.WriteString("Unregistered deployment " + args[0])
} }

View File

@ -37,14 +37,9 @@ func (m *Msg) Call() error {
// all write ops cause FS conf writes so that state is preserved // all write ops cause FS conf writes so that state is preserved
// Reads return copies of data // Reads return copies of data
type Pool struct {
High int
Low int
}
type Deployment struct { type Deployment struct {
Path string Path string
Pool Pool Pool struct{Low int; High int}
} }
type Conf struct { type Conf struct {
@ -101,8 +96,8 @@ func saveConf() error {
} }
// TODO: return copies // TODO: return copies
func GetConf() Conf { func GetConf() *Conf {
return *conf return conf
} }
func Run() { func Run() {

View File

@ -12,12 +12,14 @@ var dirToNick map[string]string = make(map[string]string)
// given a valid deployment, add it // given a valid deployment, add it
// internal, thread unsafe // internal, thread unsafe
func addDeployment(d *Msg) error { func addDeployment(msg *Msg) error {
if err := validateDeployment(d); err != nil { if err := validateDeployment(msg); err != nil {
return err return err
} }
conf.Deployments[d.Args["name"]] = d.Args["path"] var dep Deployment
dirToNick[d.Args["path"]] = d.Args["name"] dep.Path = msg.Args["path"]
conf.Deployments[msg.Args["name"]] = dep
dirToNick[msg.Args["path"]] = msg.Args["name"]
saveConf() saveConf()
return nil return nil
} }
@ -25,10 +27,10 @@ func addDeployment(d *Msg) error {
func rmDeployment(d *Msg) error { func rmDeployment(d *Msg) error {
// Assume nick, check if registered // Assume nick, check if registered
deps := GetConf().Deployments deps := GetConf().Deployments
if path,ok := deps[d.Args["arg"]]; ok { if dep,ok := deps[d.Args["arg"]]; ok {
// registered nick // registered nick
delete(deps, d.Args["arg"]) delete(deps, d.Args["arg"])
delete(dirToNick, path) delete(dirToNick, dep.Path)
saveConf() saveConf()
return nil return nil
} else { } else {

View File

@ -10,13 +10,14 @@ import (
"os/signal" "os/signal"
"strings" "strings"
"syscall" "syscall"
"bufio"
) )
var cmdSock net.Listener var cmdSock net.Listener
type SockCommand struct { type SockCommand struct {
warren.Command warren.Command
Run func(cmd *SockCommand, c net.Conn, path string, args ...string) Run func(cmd *SockCommand, writer *bufio.Writer, path string, args ...string)
} }
func (cmd *SockCommand) GetName() string { func (cmd *SockCommand) GetName() string {
@ -27,30 +28,33 @@ func (cmd *SockCommand) GetSummary() string {
return cmd.Summary return cmd.Summary
} }
func (cmd *SockCommand) Exec(c net.Conn, path string, args []string) { func (cmd *SockCommand) Exec(writer *bufio.Writer, path string, args []string) {
cmd.Flag.Usage = func() { cmd.Flag.Usage = func() {
// helpFunc(c, c.Name) // helpFunc(c, c.Name)
} }
cmd.Flag.Parse(args) cmd.Flag.Parse(args)
cmd.Run(cmd, c, path, cmd.Flag.Args()...) cmd.Run(cmd, writer, path, cmd.Flag.Args()...)
} }
func sockCmdHandle(c net.Conn) { func sockCmdHandle(c net.Conn) {
reader := bufio.NewReader(c)
writer := bufio.NewWriter(c)
defer c.Close() defer c.Close()
fmt.Println("cmdHandle") fmt.Println("cmdHandle")
data, err := warren.ReadStringz(c) data, err := reader.ReadString('\n')
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
warren.WriteStringz(c, "read error:"+err.Error()) writer.WriteString("read error:"+err.Error())
return return
} }
fmt.Println("cmdHandle got command:", string(data)) line := strings.TrimSpace(data)
fmt.Println("cmdHandle got command:", line)
// BAD: TODO: handle quotes " // BAD: TODO: handle quotes "
// path|arg1|arg2|... // path|arg1|arg2|...
args := strings.Split(data, "|") args := strings.Split(line, "|")
if len(args) < 2 { if len(args) < 2 {
warren.WriteStringz(c, "Format error") writer.WriteString("Format error")
return return
} }
@ -58,12 +62,15 @@ func sockCmdHandle(c net.Conn) {
var icmd = warren.GetCommand(args[1]) var icmd = warren.GetCommand(args[1])
// get and run cmd // get and run cmd
if icmd == nil { if icmd == nil {
warren.WriteStringz(c, "Unknown command "+args[1]) writer.WriteString("Unknown command "+args[1])
// usage ? // usage ?
return return
} }
icmd.(*SockCommand).Exec(c, args[0], args[2:]) icmd.(*SockCommand).Exec(writer, args[0], args[2:])
writer.WriteByte(0)
writer.Flush()
fmt.Println("flushed")
} }
// determine if warrend is already running // determine if warrend is already running

View File

@ -1,9 +1,7 @@
package warren package warren
import ( import (
"fmt"
"log" "log"
"net"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
@ -38,27 +36,6 @@ func AppName() string {
return name return name
} }
func WriteStringz(c net.Conn, str string) (err error) {
_, err = c.Write([]byte(str + "\000"))
return
}
func ReadStringz(c net.Conn) (string, error) {
data := ""
buf := make([]byte, 1024) // Max size of buff based on?
for len(data) == 0 || byte(data[len(data)-1]) != 0 {
nr, err := c.Read(buf)
if err != nil {
fmt.Println("readStringz read error:", err)
return "", fmt.Errorf("readStringz error:", err)
}
data += string(buf[0:nr])
}
//return minux \000
return data[0 : len(data)-1], nil
}
func AbsPath(wd, path string) string { func AbsPath(wd, path string) string {
// ./local_path // ./local_path
if path[0] == '.' { if path[0] == '.' {