Skip to content

Commit

Permalink
Fixes samuel#62 return error on empty path in Set
Browse files Browse the repository at this point in the history
ZooKeeper seemingly has a bug in which if it receives a Set request with
an empty path then it'll take down the server. This change returns a
client side error on empty paths as it's not a valid request regardless.
  • Loading branch information
samuel committed Jun 10, 2015
1 parent f575d97 commit 3b4d6af
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
language: go
go:
- 1.4
- 1.4.2

sudo: false

Expand Down
20 changes: 16 additions & 4 deletions zk/conn.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package zk is a native Go client library for the ZooKeeper orchestration service.
package zk

/*
Expand All @@ -22,10 +23,16 @@ import (
"time"
)

var (
ErrNoServer = errors.New("zk: could not connect to a server")
DefaultLogger = defaultLogger{}
)
// ErrNoServer indicates that an operation cannot be completed
// because attempts to connect to all servers in the list failed.
var ErrNoServer = errors.New("zk: could not connect to a server")

// ErrInvalidPath indicates that an operation was being attempted on
// an invalid path. (e.g. empty path)
var ErrInvalidPath = errors.New("zk: invalid path")

// DefaultLogger uses the stdlib log package for logging.
var DefaultLogger = defaultLogger{}

const (
bufferSize = 1536 * 1024
Expand All @@ -49,6 +56,7 @@ type watchPathType struct {

type Dialer func(network, address string, timeout time.Duration) (net.Conn, error)

// Logger is an interface that can be implemented to provide custom log output.
type Logger interface {
Printf(string, ...interface{})
}
Expand Down Expand Up @@ -191,6 +199,7 @@ func (c *Conn) Close() {
}
}

// States returns the current state of the connection.
func (c *Conn) State() State {
return State(atomic.LoadInt32((*int32)(&c.state)))
}
Expand Down Expand Up @@ -709,6 +718,9 @@ func (c *Conn) GetW(path string) ([]byte, *Stat, <-chan Event, error) {
}

func (c *Conn) Set(path string, data []byte, version int32) (*Stat, error) {
if path == "" {
return nil, ErrInvalidPath
}
res := &setDataResponse{}
_, err := c.request(opSetData, &SetDataRequest{path, data, version}, res, nil)
return &res.Stat, err
Expand Down
11 changes: 11 additions & 0 deletions zk/structs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,14 @@ func TestDecodeShortBuffer(t *testing.T) {
return
}
}

func BenchmarkEncode(b *testing.B) {
buf := make([]byte, 4096)
st := &connectRequest{Passwd: []byte("1234567890")}
b.ReportAllocs()
for i := 0; i < b.N; i++ {
if _, err := encodePacket(buf, st); err != nil {
b.Fatal(err)
}
}
}

0 comments on commit 3b4d6af

Please sign in to comment.