discoverd

package
v0.0.0-...-dd9b67b Latest Latest
Warning

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

Go to latest
Published: Aug 2, 2014 License: BSD-3-Clause, MIT Imports: 10 Imported by: 0

README

go-discoverd

Go client for discoverd

Flynn

Flynn is a modular, open source Platform as a Service (PaaS).

If you're new to Flynn, start here.

Status

Flynn is in active development and currently unsuitable for production use.

Users are encouraged to experiment with Flynn but should assume there are stability, security, and performance weaknesses throughout the project. This warning will be removed when Flynn is ready for production use.

Please report bugs as issues on the appropriate repository. If you have a general question or don't know which repo to use, report them here.

Contributing

We welcome and encourage community contributions to Flynn.

Since the project is still unstable, there are specific priorities for development. Pull requests that do not address these priorities will not be accepted until Flynn is production ready.

Please familiarize yourself with the Contribution Guidelines and Project Roadmap before contributing.

There are many ways to help Flynn besides contributing code:

  • Fix bugs or file issues
  • Improve the documentation including this website
  • Contribute financially to support core development

Flynn is a trademark of Prime Directive, Inc.

Documentation

Overview

Client library for discoverd that gives you service discovery and registration, as well as basic leader election coordination. It provides a high-level API around the lower-level service API of the discoverd service.

Index

Examples

Constants

View Source
const DefaultTimeout = time.Second

This is a reasonable default value to be used for the timeout in the Services method.

Variables

View Source
var ErrUnknownRegistration = errors.New("discover: unknown registration")

ErrUnknownRegistration is returned by Unregister when no registration is found.

Functions

func Connect

func Connect(addr string) error

Connect explicitly initializes DefaultClient. If addr is empty, the default address is used. If DefaultClient has already been created it is a no-op.

func Register

func Register(name, addr string) error

Register will announce a service as available and online at the address specified. If you only specify a port as the address, discoverd may expand it to a full host and port based on the external IP of the discoverd agent.

func RegisterAndStandby

func RegisterAndStandby(name, addr string, attributes map[string]string) (chan *Service, error)

RegisterAndStandby will register a service and returns a channel that will only be fired when this service is or becomes leader. This can be used to implement a standby mode, where your service doesn't actually start serving until it becomes a leader. You can also use this for more standard leader election upgrades by placing the receive for this channel in a goroutine.

Example (Standby)
standbyCh, err := discoverd.RegisterAndStandby("sampi", ":9099", nil)
if err != nil {
	panic(err)
}
<-standbyCh
// run server
Output:

Example (Upgrade)
standbyCh, err := discoverd.RegisterAndStandby("sampi", ":9099", nil)
if err != nil {
	panic(err)
}
go func() {
	<-standbyCh
	// upgrade to leader
}()
// run server
Output:

func RegisterWithAttributes

func RegisterWithAttributes(name, addr string, attributes map[string]string) error

RegisterWithAttributes registers a service to be discovered, setting the attribtues specified, however, attributes are optional so the value can be nil. If you need to change attributes, you just reregister.

func Unregister

func Unregister(name, addr string) error

Unregister will explicitly unregister a service and as such it will stop any heartbeats being sent from this client.

func UnregisterAll

func UnregisterAll() error

UnregisterAll will call Unregister on all services that have been registered with this client.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

A Client maintains the RPC client connection and any active registered services, making sure they receive their heartbeat calls.

var DefaultClient *Client

DefaultClient is used by all of the top-level functions. Connect must be called before using it directly.

func NewClient

func NewClient() (*Client, error)

By default, NewClient will produce a client that will connect to the default address for discoverd, which is 127.0.0.1:1111, or whatever the value of the environment variable DISCOVERD.

func NewClientWithAddr

func NewClientWithAddr(addr string) (*Client, error)

func NewClientWithRPCClient

func NewClientWithRPCClient(c *rpcplus.Client) *Client

func (*Client) Close

func (c *Client) Close() error

func (*Client) NewServiceSet

func (c *Client) NewServiceSet(name string) (ServiceSet, error)

NewServiceSet will produce a ServiceSet for a given service name.

func (*Client) Register

func (c *Client) Register(name, addr string) error

Register will announce a service as available and online at the address specified. If you only specify a port as the address, discoverd may expand it to a full host and port based on the external IP of the discoverd agent.

func (*Client) RegisterAndStandby

func (c *Client) RegisterAndStandby(name, addr string, attributes map[string]string) (chan *Service, error)

RegisterAndStandby will register a service and returns a channel that will only be fired when this service is or becomes leader. This can be used to implement a standby mode, where your service doesn't actually start serving until it becomes a leader. You can also use this for more standard leader election upgrades by placing the receive for this channel in a goroutine.

func (*Client) RegisterWithAttributes

func (c *Client) RegisterWithAttributes(name, addr string, attributes map[string]string) error

RegisterWithAttributes registers a service to be discovered, setting the attribtues specified, however, attributes are optional so the value can be nil. If you need to change attributes, you just reregister.

func (*Client) RegisterWithSet

func (c *Client) RegisterWithSet(name, addr string, attributes map[string]string) (ServiceSet, error)

RegisterWithSet combines service registration with NewServiceSet for the same service, but will not include the registered service in the ServiceSet. If you have a cluster of services that all connect to a leader, this is especially useful as you don't have to worry about not connecting to yourself. When using Leader or Leaders with RegisterWithSet, you may still get a Service representing the service registered, in case this service does become leader. In that case, you can use the SelfAddr property of ServiceSet to compare to the Service returned by Leader.

func (*Client) Services

func (c *Client) Services(name string, timeout time.Duration) ([]*Service, error)

Services returns an array of Service objects of a given name. It provides a much easier way to get at a snapshot of services than using ServiceSet. It will also block until at least one service is available, or until the timeout specified is exceeded.

func (*Client) Unregister

func (c *Client) Unregister(name, addr string) error

Unregister will explicitly unregister a service and as such it will stop any heartbeats being sent from this client.

func (*Client) UnregisterAll

func (c *Client) UnregisterAll() error

UnregisterAll will call Unregister on all services that have been registered with this client.

type Service

type Service struct {
	Created uint
	Name    string
	Host    string
	Port    string
	Addr    string
	Attrs   map[string]string
}

This is how we model a service. It's simply a named address with optional attributes. It also has a field to determine age, which is used for leader election.

func Services

func Services(name string, timeout time.Duration) ([]*Service, error)

Services returns an array of Service objects of a given name. It provides a much easier way to get at a snapshot of services than using ServiceSet. It will also block until at least one service is available, or until the timeout specified is exceeded.

type ServiceSet

type ServiceSet interface {
	SelfAddr() string

	// Leader returns the current leader for a ServiceSet. It's calculated by choosing the oldest
	// service in the set. This "lockless" approach means for any consistent set (same service, same
	// filters) there is always an agreed upon leader.
	Leader() *Service

	// Leaders returns a channel that will first produce the current leader service, then any following
	// leader service as the leader of the set changes. Every call to Leaders produces a new watch on
	// the set, and once you get a channel from Leaders, you *must* always be receiving until the
	// ServiceSet is closed. A nil value will be sent if there are no members of the set.
	Leaders() chan *Service

	// Services returns an array of Service objects in the set, sorted by age. This means that most
	// of the time, the first element is the leader. However, in cases where the ServiceSet was
	// created by RegisterWithSet, the registered service will not be included in this list, so you
	// should rely on Leader/Leaders to get the leader.
	Services() []*Service

	// Addrs returns an array of strings representing the addresses of the services.
	Addrs() []string

	// Select will return an array of services with matching attributes to the provided map argument.
	// Unlike the Services method, Select is not ordered.
	Select(attrs map[string]string) []*Service

	// Filter will set the filter map for a ServiceSet. A filter will limit services that show up in
	// the set to only the ones with matching attributes. Any services in the set that don't match
	// when Filter is called will be removed from the ServiceSet.
	Filter(attrs map[string]string)

	// Watch gives you a channel of updates that are made to the ServiceSet. Once you create a watch,
	// you must always be receiving on it until the ServiceSet is closed or you call Unwatch with the
	// channel.
	//
	// The bringCurrent argument will produce a channel that will have buffered in it updates
	// representing the current services in the set. Otherwise, the channel returned will be
	// unbuffered.
	Watch(bringCurrent bool) chan *agent.ServiceUpdate

	// Unwatch removes a channel from the watch list of the ServiceSet. It will also close the channel.
	Unwatch(chan *agent.ServiceUpdate)

	// Close will stop a ServiceSet from being updated.
	Close() error
}

A ServiceSet is long-running query of services, giving you a real-time representation of a service cluster. Using the same ServiceSet across services/processes gives you a consistent collection of services that leader election can be coordinated with.

func NewServiceSet

func NewServiceSet(name string) (ServiceSet, error)

NewServiceSet will produce a ServiceSet for a given service name.

func RegisterWithSet

func RegisterWithSet(name, addr string, attributes map[string]string) (ServiceSet, error)

RegisterWithSet combines service registration with NewServiceSet for the same service, but will not include the registered service in the ServiceSet. If you have a cluster of services that all connect to a leader, this is especially useful as you don't have to worry about not connecting to yourself. When using Leader or Leaders with RegisterWithSet, you may still get a Service representing the service registered, in case this service does become leader. In that case, you can use the SelfAddr property of ServiceSet to compare to the Service returned by Leader.

Example (UpgradeDowngrade)
set, _ := discoverd.RegisterWithSet("cluster", ":9099", nil)
go func() {
	leaders := set.Leaders()
	currentLeader := false
	for leader := range leaders {
		if leader.Addr == set.SelfAddr() {
			currentLeader = true
			// upgrade to leader
		} else if currentLeader == true {
			currentLeader = false
			// downgrade from leader
		}
	}
}()
// run server
Output:

Directories

Path Synopsis
package balancer provides reference implementations for common load balancing techniques across service sets.
package balancer provides reference implementations for common load balancing techniques across service sets.

Jump to

Keyboard shortcuts

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