summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Cully <bjc@kublai.com>2015-07-10 19:18:55 +0000
committerBrian Cully <bjc@kublai.com>2015-07-10 19:27:01 +0000
commit2fd292d5f480fd51cdbbff4821b6f09940a005a9 (patch)
treee3b4a2c4bb074133fe7a3625c01d256078f00968
parent9408742ed1a7eef568e2bf0d8e1aba390ae4d80b (diff)
downloadgoctl-2fd292d5f480fd51cdbbff4821b6f09940a005a9.tar.gz
goctl-2fd292d5f480fd51cdbbff4821b6f09940a005a9.zip
Change Handler type to interface.
Should allow for more flexibility in handlers. Also, move builtin handlers into their own modules
-rw-r--r--cmd_pid.go23
-rw-r--r--cmd_ping.go15
-rw-r--r--goctl.go50
-rw-r--r--goctl_test.go42
4 files changed, 82 insertions, 48 deletions
diff --git a/cmd_pid.go b/cmd_pid.go
new file mode 100644
index 0000000..00f127f
--- /dev/null
+++ b/cmd_pid.go
@@ -0,0 +1,23 @@
+package goctl
+
+import (
+ "os"
+ "strconv"
+)
+
+var pid string
+
+type cmdPID struct{}
+
+func (cmd cmdPID) Name() string {
+ return "pid"
+}
+
+func (cmd cmdPID) Run(_ []string) string {
+ return pid
+}
+
+func init() {
+ pid = strconv.Itoa(os.Getpid())
+ builtinHandlers = append(builtinHandlers, cmdPID{})
+}
diff --git a/cmd_ping.go b/cmd_ping.go
new file mode 100644
index 0000000..9da8d96
--- /dev/null
+++ b/cmd_ping.go
@@ -0,0 +1,15 @@
+package goctl
+
+type cmdPing struct{}
+
+func (cmd *cmdPing) Name() string {
+ return "ping"
+}
+
+func (cmd *cmdPing) Run(_ []string) string {
+ return "pong"
+}
+
+func init() {
+ builtinHandlers = append(builtinHandlers, &cmdPing{})
+}
diff --git a/goctl.go b/goctl.go
index 12e181a..a94122a 100644
--- a/goctl.go
+++ b/goctl.go
@@ -7,7 +7,6 @@ import (
"io"
"net"
"os"
- "strconv"
"strings"
"sync/atomic"
"time"
@@ -18,19 +17,12 @@ import (
// How long to wait for a response before returning an error.
const timeout = 100 * time.Millisecond
-// Built-in commands.
-const (
- cmdPing = "ping"
- cmdPID = "pid"
-)
-
-var builtinHandlers []*Handler
+var builtinHandlers []Handler
// Error returned if handler already exists.
var HandlerExists error
var (
- pid int
lastid uint64
Logger log15.Logger
)
@@ -39,31 +31,25 @@ type Goctl struct {
logger log15.Logger
path string
listener net.Listener
- handlers map[string]*Handler
+ handlers map[string]Handler
}
-type Handler struct {
- Name string
- Fn func([]string) string
+type Handler interface {
+ Name() string
+ Run([]string) string
}
func init() {
- pid = os.Getpid()
Logger = log15.New()
Logger.SetHandler(log15.DiscardHandler())
HandlerExists = errors.New("handler exists")
-
- builtinHandlers = []*Handler{
- {cmdPing, handlePing},
- {cmdPID, handlePID},
- }
}
func NewGoctl(path string) Goctl {
- handlers := make(map[string]*Handler)
+ handlers := make(map[string]Handler)
for _, h := range builtinHandlers {
- handlers[h.Name] = h
+ handlers[h.Name()] = h
}
return Goctl{
logger: Logger.New("id", atomic.AddUint64(&lastid, 1)),
@@ -102,16 +88,16 @@ func (gc *Goctl) Stop() {
}
}
-func (gc *Goctl) AddHandler(name string, fn func([]string) string) error {
- return gc.AddHandlers([]*Handler{{name, fn}})
+func (gc *Goctl) AddHandler(h Handler) error {
+ return gc.AddHandlers([]Handler{h})
}
-func (gc *Goctl) AddHandlers(handlers []*Handler) error {
+func (gc *Goctl) AddHandlers(handlers []Handler) error {
for _, h := range handlers {
- if gc.handlers[h.Name] != nil {
+ if gc.handlers[h.Name()] != nil {
return HandlerExists
}
- gc.handlers[h.Name] = h
+ gc.handlers[h.Name()] = h
}
return nil
}
@@ -145,14 +131,6 @@ func Write(w io.Writer, p []byte) error {
return nil
}
-func handlePing(args []string) string {
- return "pong"
-}
-
-func handlePID(args []string) string {
- return strconv.Itoa(pid)
-}
-
func (gc *Goctl) acceptor() {
for {
c, err := gc.listener.Accept()
@@ -180,7 +158,7 @@ func (gc *Goctl) reader(c io.ReadWriteCloser) error {
gc.logger.Debug("Got command.", "cmd", cmd)
var resp string
if h := gc.handlers[cmd[0]]; h != nil {
- resp = h.Fn(cmd[1:])
+ resp = h.Run(cmd[1:])
} else {
resp = fmt.Sprintf("ERROR: unknown command: '%s'.", cmd[0])
}
@@ -198,7 +176,7 @@ func (gc *Goctl) isAlreadyRunning() string {
defer c.Close()
dataChan := make(chan []byte, 1)
- c.Write([]byte(cmdPID))
+ c.Write([]byte("pid"))
go func() {
buf := make([]byte, 1024)
n, err := c.Read(buf[:])
diff --git a/goctl_test.go b/goctl_test.go
index a1e4711..a4a1041 100644
--- a/goctl_test.go
+++ b/goctl_test.go
@@ -9,6 +9,23 @@ import (
"testing"
)
+type testHandler struct {
+ name string
+ fn func([]string) string
+}
+
+func makeHandler(name string, fn func(_ []string) string) testHandler {
+ return testHandler{name: name, fn: fn}
+}
+
+func (th testHandler) Name() string {
+ return th.name
+}
+
+func (th testHandler) Run(args []string) string {
+ return th.fn(args)
+}
+
var sockpath string
func init() {
@@ -98,12 +115,12 @@ func TestAddHandler(t *testing.T) {
gc := start(t)
defer gc.Stop()
- gc.AddHandler("foo", func(args []string) string {
+ gc.AddHandler(makeHandler("foo", func(args []string) string {
if !reflect.DeepEqual(args, []string{"bar", "baz"}) {
t.Errorf("Got %v, expected ['bar', 'baz']", args)
}
return "bar baz"
- })
+ }))
c := dial(t)
defer c.Close()
@@ -121,19 +138,20 @@ func TestAddHandlers(t *testing.T) {
gc := start(t)
defer gc.Stop()
- gc.AddHandlers([]*Handler{
- {"foo", func(args []string) string {
+ gc.AddHandlers([]Handler{
+ makeHandler("foo", func(args []string) string {
if !reflect.DeepEqual(args, []string{"bar", "baz"}) {
t.Errorf("Got %v, expected ['bar', 'baz']", args)
}
return ""
- }},
- {"bar", func(args []string) string {
+ }),
+ makeHandler("bar", func(args []string) string {
if !reflect.DeepEqual(args, []string{"baz", "pham"}) {
t.Errorf("Got %v, expected ['baz', 'pham']", args)
}
return "wauug"
- }}})
+ }),
+ })
c := dial(t)
defer c.Close()
@@ -158,15 +176,15 @@ func TestCannotOverrideExtantHandlers(t *testing.T) {
gc := start(t)
defer gc.Stop()
- err := gc.AddHandler("ping", func(args []string) string {
+ err := gc.AddHandler(makeHandler("ping", func(args []string) string {
return "gnip"
- })
+ }))
if err != HandlerExists {
t.Error("Was able to override built-in ping handler.")
}
- err = gc.AddHandlers([]*Handler{
- {"foo", func(args []string) string { return "foo" }},
- {"foo", func(args []string) string { return "foo" }},
+ err = gc.AddHandlers([]Handler{
+ makeHandler("foo", func(args []string) string { return "foo" }),
+ makeHandler("foo", func(args []string) string { return "foo" }),
})
if err != HandlerExists {
t.Error("Was able to assign two handlers for 'foo'.")