88 lines
1.6 KiB
Go
88 lines
1.6 KiB
Go
package zoo
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/samuel/go-zookeeper/zk"
|
|
)
|
|
|
|
const (
|
|
defaultSessionTimeout = 60 * time.Second
|
|
currentPath = "."
|
|
)
|
|
|
|
var zkSessionTimeout = defaultSessionTimeout
|
|
|
|
type client2 struct {
|
|
*zk.Conn
|
|
path string
|
|
done chan struct{} // signal chan, closes when the underlying connection terminates
|
|
stopOnce sync.Once
|
|
}
|
|
|
|
func connect2(hosts []string, path string) (*client2, error) {
|
|
c, ev, err := zk.Connect(hosts, zkSessionTimeout)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
done := make(chan struct{})
|
|
go func() {
|
|
// close the 'done' chan when the zk event chan closes (signals termination of zk connection)
|
|
defer close(done)
|
|
for {
|
|
if _, ok := <-ev; !ok {
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
return &client2{
|
|
Conn: c,
|
|
path: path,
|
|
done: done,
|
|
}, nil
|
|
}
|
|
|
|
func (c *client2) stopped() <-chan struct{} {
|
|
return c.done
|
|
}
|
|
|
|
func (c *client2) stop() {
|
|
c.stopOnce.Do(c.Close)
|
|
}
|
|
|
|
func (c *client2) data(path string) (data []byte, err error) {
|
|
data, _, err = c.Get(path)
|
|
return
|
|
}
|
|
|
|
func (c *client2) watchChildren(path string) (string, <-chan []string, <-chan error) {
|
|
errCh := make(chan error, 1)
|
|
snap := make(chan []string)
|
|
|
|
watchPath := c.path
|
|
if path != "" && path != currentPath {
|
|
watchPath = watchPath + path
|
|
}
|
|
go func() {
|
|
defer close(errCh)
|
|
for {
|
|
children, _, ev, err := c.ChildrenW(watchPath)
|
|
if err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
select {
|
|
case snap <- children:
|
|
case <-c.done:
|
|
return
|
|
}
|
|
e := <-ev // wait for the next watch-related event
|
|
if e.Err != nil {
|
|
errCh <- e.Err
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
return watchPath, snap, errCh
|
|
}
|