ezk

package module
v0.0.0-...-4045ee1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 15, 2016 License: MIT Imports: 5 Imported by: 2

README

ezk

Enhanced Zookeeper Client

docs: https://godoc.org/github.com/betable/ezk

Documentation

Overview

Package ezk is an enhanced Zookeeper client. It uses the connection and underlying operations from https://github.com/samuel/go-zookeeper/zk in conjunction with automatic retry of operations via the https://github.com/betable/retry library.

ABOUT THE CHROOT PREFIX, ABSOLUTE PATHS, AND RELATIVE PATHS
===========================================================

Examples of Chroot prefixes commonly used are
 "/production/", "/staging/", and "/devtest/".
These prefixes let one multitask the Zookeeper
cluster for different responsibilities without
incurring crosstalk between applications.

The Chroot prefix is implicitly prepended to any
relative path supplied to an ezk API call.

Our (enforced) zookeeper path convention for the
ClientConfig.Chroot string allows us to distinguish
between chroot-ed paths and non-chroot paths, and
between absolute versus relative paths as follows:

* the Chroot prefix must always start with a forward slash.
A single '/' alone is a valid Chroot prefix. If the prefix
is longer than one character, the Chroot prefix must
also end with a '/' as well--in this case the prefix will
contain exactly two '/' slash characters; one at the
beginning and one at the end.

A Chroot prefix therefore names either zero or one
znodes.

For example: "/prod/", "/staging/", and "/devtest/" are all
legal Chroot strings. Counter-examples: "/prod" is not
a legal Chroot value, nor is "prod/", nor is "prod".
User code can distinguish Chroot prefixes by checking
whether the first byte of the string is '/' or not.
See the IsAbsolutePath() and RemoveChroot()
helper functions.

* All paths that are intended to be relative to the Chroot
prefix must *not* start with a forward slash and must
not end with a forward slash; they are like relative paths in Unix.

So legal examples of relative paths: "myservice/config/my-servers",
"piper", or "timeseries", or "timeseries/config". The
requirement forbidding the trailing '/' is enforced on the
Zookeeper server side.

* The ezk library will form the full path (spoken on the wire to
the Zookeeper) by a simple concatenation of Chroot + relative path.

* The helper function RemoveChroot(path) will detect and
automatically remove any chroot prefix from path, and returns a
relative path. It will leave untouched already relative paths.

* Important: when receiving watch events on channels from the
github.com/samuel/go-zookeeper/zk library, they are of the
following Event type. See the notes on the Path field below.

type Event struct {
    Type   EventType
    State  State

    // Path is for non-session events; it is
    // the (absolute, Chroot-prefixed) path
    // of the watched node. [1]
    Path   string

    Err    error
    Server string // For connection events
}

Note [1] that this Path is absolute, it includes the Chroot
prefix. Users should call RemoveChroot() function as needed
before using the Event.Path field if they require a relative
path.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ChompSlash

func ChompSlash(path string) string

ChompSlash removes any trailing single '/' from path. It only checks the very last character.

func DefaultRetry

func DefaultRetry(op, path string, f func() error)

The DefaultRetry function will retry four times if the first Zookeeper call fails, after sleeping in turn: 0ms, 100ms, 500ms and 1500ms.

func IsAbsolutePath

func IsAbsolutePath(path string) bool

IsAbsolutePath() checks to see if the path starts with a Chroot element by checking if the first byte is a '/' or not.

func RemoveChroot

func RemoveChroot(path string) string

RemoveChroot(path) will detect and automatically remove any chroot prefix, and return a relative path.

Examples: "/mybase/myservice/config" -> "myservice/config"

"/myroot/alist" -> "alist"
"/hello/" -> ""
"/poorlyFormed" -> ""  ## properly should have a trailling slash
"relative/path/unchanged" -> "relative/path/unchanged"

RemoveChroot will leave untouched any already relative paths. Note that this returned relative path may be the empty string "" if path consists of one element "/chroot/" alone, for example.

Types

type Client

type Client struct {

	// The configuration for the client.
	Cfg ClientConfig

	// The underlying github.com/samuel/go-zookeeper/zk connection.
	Conn *zk.Conn

	// WatchCh will be nil until Connect returns without error.
	// Watches that fire over the Zookeeper connection will be
	// received on WatchCh.
	WatchCh <-chan zk.Event
}

Client is a wrapper over github.com/samuel/go-zookeeper/zk that retries all but one of its operations according to the ClientConfig.Retry function. The one exception is for CreateProtectedEphemeralSequential(); it is not retried automatically.

Example

In the example code, the goal is to set the value newURL into the node /chroot/service-name/config/server-url-list

newURL := "http://my-new-url.org:343/hello/enhanced-zookeeper-client"

base := "/chroot/"
path := "service-name/config/server-url-list"
zkCfg := ClientConfig{
	Servers:        []string{"127.0.0.1:2181"},
	Acl:            zook.WorldACL(zook.PermAll),
	Chroot:         base,
	SessionTimeout: 10 * time.Second,
}
zk := NewClient(zkCfg)
err := zk.Connect()
if err != nil {
	panic(err)
}

defer zk.Close()

err = zk.CreateDir(path, nil)
if err != nil {
	panic(err)
}

err = zk.DeleteNode(path) // delete any old value
if err != nil {
	panic(err)
}

err = zk.CreateNode(path)
if err != nil {
	panic(err)
}

_, err = zk.Set(path, []byte(newURL), -1)
if err != nil {
	panic(err)
}
Output:

func NewClient

func NewClient(cfg ClientConfig) *Client

NewClient creates a new ezk.Client. If the cfg.SessionTimout is set to 0 a default value of 10 seconds will be used. If cfg.Retry is nil then the DefaultRetry function will be used. If cfg.Acl is length 0 then zk.WorldACL(zk.PermAll) will be used.

func (*Client) Children

func (z *Client) Children(path string) (c []string, s *zk.Stat, err error)

Children returns the children of a znode. z.Cfg.Chroot will be prepended to a relative path. The call will be retried.

func (*Client) ChildrenW

func (z *Client) ChildrenW(path string) (c []string, s *zk.Stat, ch <-chan zk.Event, err error)

ChildrenW returns the children of a znode and sets a watch. z.Cfg.Chroot will be prepended to a relative path. The call will be retried.

func (*Client) Close

func (z *Client) Close()

Close closes the connection to the Zookeeper server.

func (*Client) Connect

func (z *Client) Connect() error

Connect connects to a Zookeeper server. Upon success it sets the z.WatchCh and z.Conn and returns nil. If an error is returned then z.WatchCh and z.Conn will not be set. Connect() will typically only be needed once, but can be called again if need be. Upon successful connection to Zookeeper, we will attempt to create the z.Cfg.Chroot node. No error will be returned if this attempt fails, as commonly it may already exist.

func (*Client) Create

func (z *Client) Create(path string, data []byte, flags int32, acl []zk.ACL) (s string, err error)

Create creates a znode with a content. If acl is nil then the z.Cfg.Acl set will be applied to the new znode. z.Cfg.Chroot will be prepended to a relative path. The call will be retried.

func (*Client) CreateDir

func (z *Client) CreateDir(path string, acl []zk.ACL) error

CreateDir is a helper method that creates a path of empty znodes if they do not exist. It acts like os.MkdirAll or mkdir -p in that it will create a series of nested directories if the path supplies them. It won't fail if some or all of these already exist. z.Cfg.Chroot will be prepended to a relative path. The call will be retried.

func (*Client) CreateNode

func (z *Client) CreateNode(path string) error

A convenience version of Create, CreateNode supplies empty data, 0 flags, and the default z.Cfg.Acl list to a z.Create() call. z.Cfg.Chroot will be prepended to a relative path. The call will be retried.

func (*Client) CreateProtectedEphemeralSequential

func (z *Client) CreateProtectedEphemeralSequential(path string, data []byte, acl []zk.ACL) (string, error)

CreateProtectedEphemeralSequential creates a sequential ephemeral znode. z.Cfg.Chroot will be prepended to a relative path. The call will be NOT be retried.

func (*Client) Delete

func (z *Client) Delete(path string, version int32) (err error)

Delete deletes a znode. z.Cfg.Chroot will be prepended to a relative path. The call will be retried.

func (*Client) DeleteNode

func (z *Client) DeleteNode(path string) error

A convenience version of Delete, DeleteNode deletes a znode, using version -1 to delete any version. z.Cfg.Chroot will be prepended to a relative path. The call will be retried.

func (*Client) DeleteNodeRecursively

func (z *Client) DeleteNodeRecursively(path string) error

A convenience version of Delete, DeleteNodeRecursively deletes a znode and any of its children, using version -1 to delete any version. z.Cfg.Chroot will be prepended to a relative path. The call will be retried.

func (*Client) Exists

func (z *Client) Exists(path string) (ok bool, s *zk.Stat, err error)

Exists checks if a znode exists. z.Cfg.Chroot will be prepended to a relative path. The call will be retried.

func (*Client) ExistsW

func (z *Client) ExistsW(path string) (ok bool, s *zk.Stat, ch <-chan zk.Event, err error)

ExistsW returns if a znode exists and sets a watch. z.Cfg.Chroot will be prepended to a relative path. The call will be retried.

func (*Client) Get

func (z *Client) Get(path string) (d []byte, s *zk.Stat, err error)

Get returns the contents of a znode. z.Cfg.Chroot will be prepended to a relative path. The call will be retried.

func (*Client) GetACL

func (z *Client) GetACL(path string) (a []zk.ACL, s *zk.Stat, err error)

GetACL returns the ACL for a znode. z.Cfg.Chroot will be prepended to a relative path. The call will be retried.

func (*Client) GetW

func (z *Client) GetW(path string) (d []byte, s *zk.Stat, ch <-chan zk.Event, err error)

GetW returns the contents of a znode and sets a watch. z.Cfg.Chroot will be prepended to a relative path. The call will be retried.

func (*Client) SafeGet

func (z *Client) SafeGet(path string) ([]byte, *zk.Stat, error)

SafeGet is a helper method that syncs Zookeeper and return the content of a znode. z.Cfg.Chroot will be prepended to a relative path. The call will be retried.

func (*Client) SafeSet

func (z *Client) SafeSet(path string, data []byte, version int32, acl []zk.ACL) (*zk.Stat, error)

SafeSet is a helper method that writes a znode creating it first if it does not exists. It will sync the Zookeeper before checking if the node exists. z.Cfg.Chroot will be prepended to a relative path. The call will be retried.

func (*Client) Set

func (z *Client) Set(path string, data []byte, version int32) (s *zk.Stat, err error)

Set writes content in an existent znode. z.Cfg.Chroot will be prepended to a relative path. The call will be retried.

func (*Client) SetACL

func (z *Client) SetACL(path string, acl []zk.ACL, version int32) (s *zk.Stat, err error)

SetACL sets a ACL to a znode. z.Cfg.Chroot will be prepended to a relative path. The call will be retried.

func (*Client) Sync

func (z *Client) Sync(path string) (s string, err error)

Sync performs a sync from the master in the Zookeeper server. z.Cfg.Chroot will be prepended to a relative path. The call will be retried.

type ClientConfig

type ClientConfig struct {

	// The Chroot directory will be prepended to all paths
	Chroot string

	// The set of ACLs used by defeault when
	// calling Client.Create(), if the formal
	// parameter acl in Create() is length 0.
	Acl []zk.ACL

	// The URLs of the zookeepers to attempt to connect to.
	Servers []string

	// SessionTimeout defaults to 10 seconds if not
	// otherwise set.
	SessionTimeout time.Duration

	// The Retry function determines how many times
	// and how often we retry our Zookeeper operations
	// before failing. See DefaultRetry() which is
	// used if this is not otherwise set.
	Retry Retry
}

ClientConfig is used to configure a Client; pass it to NewClient().

type Retry

type Retry func(op, path string, f func() error)

Retry defines the type of the retry method to use.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL