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

View File

@ -3,7 +3,9 @@ package main
import (
"github.com/dballard/warren/cmd/warrend/conf"
"github.com/dballard/warren/lib/warren"
"net"
"strconv"
"bufio"
"fmt"
)
var listUsage = `
@ -19,16 +21,16 @@ var listCmd = &SockCommand{
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" {
warren.WriteStringz(c, cmd.Usage)
writer.WriteString(cmd.Usage)
return
}
warren.WriteStringz(c, "List\n")
for n, p := range conf.GetConf().Deployments {
warren.WriteStringz(c, n+": "+p+"\n")
writer.WriteString("List\n")
fmt.Print("List\n")
for name, dep := range conf.GetConf().Deployments {
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 (
//"github.com/dballard/warren/cmd/warrend/conf"
"github.com/dballard/warren/lib/warren"
"net"
"bufio"
"strings"
)
@ -22,21 +22,21 @@ var poolCmd = &SockCommand{
// pool [name] -- get
// 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" {
warren.WriteStringz(c, cmd.Usage)
writer.WriteString(cmd.Usage)
return
}
// GET
if len(args) == 1 {
warren.WriteStringz(c, "Pool GET " + strings.Join(args, ", ") + "\n")
writer.WriteString("Pool GET " + strings.Join(args, ", ") + "\n")
return
}
if len(args) == 3 {
warren.WriteStringz(c, "Pool SET\n")
writer.WriteString("Pool SET\n")
return
}
warren.WriteStringz(c, cmd.Usage)
writer.WriteString(cmd.Usage)
return
}

View File

@ -3,7 +3,7 @@ package main
import (
"github.com/dballard/warren/cmd/warrend/conf"
"github.com/dballard/warren/lib/warren"
"net"
"bufio"
"strings"
)
@ -33,9 +33,9 @@ var unregCmd = &SockCommand{
}
// reg path [nickname]
func regRun(cmd *SockCommand, c net.Conn, path string, args ...string) {
if (len(args) > 0 && args[0] == "help") || len(args) < 1 {
warren.WriteStringz(c, cmd.Usage)
func regRun(cmd *SockCommand, writer *bufio.Writer, path string, args ...string) {
if len(args) == 0 || args[0] == "" || (len(args) > 0 && args[0] == "help") {
writer.WriteString(cmd.Usage)
return
}
@ -58,18 +58,18 @@ func regRun(cmd *SockCommand, c net.Conn, path string, args ...string) {
err := d.Call()
if err != nil {
warren.WriteStringz(c, "ERROR: "+err.Error())
writer.WriteString("ERROR: "+err.Error())
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 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 {
warren.WriteStringz(c, cmd.Usage)
writer.WriteString(cmd.Usage)
return
}
@ -78,10 +78,10 @@ func unregRun(cmd *SockCommand, c net.Conn, path string, args ...string) {
d.Args["path"] = path
err := d.Call()
if err != nil {
warren.WriteStringz(c, "ERROR: " + err.Error())
writer.WriteString("ERROR: " + err.Error())
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
// Reads return copies of data
type Pool struct {
High int
Low int
}
type Deployment struct {
Path string
Pool Pool
Pool struct{Low int; High int}
}
type Conf struct {
@ -101,8 +96,8 @@ func saveConf() error {
}
// TODO: return copies
func GetConf() Conf {
return *conf
func GetConf() *Conf {
return conf
}
func Run() {

View File

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

View File

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

View File

@ -1,9 +1,7 @@
package warren
import (
"fmt"
"log"
"net"
"os"
"os/exec"
"path/filepath"
@ -38,27 +36,6 @@ func AppName() string {
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 {
// ./local_path
if path[0] == '.' {