Commit fd4b1c84 authored by ale's avatar ale

more documentation

parent b0c130c5
// Package masterelection lets you run a simple master-election
// protocol on top of etcd.
package masterelection
import (
......@@ -16,6 +18,9 @@ const (
RoleMaster
)
// How long to sleep on etcd Create() errors.
var errorDelay = 200 * time.Millisecond
// Role of a participant in the master election protocol.
type Role int
......@@ -213,6 +218,7 @@ func (m *MasterElection) runSlave(index uint64, stop chan bool) {
// Run the master election protocol, until the stop channel is closed.
func (m *MasterElection) Run(stop chan bool) {
// If an update channel is set, close it on exit.
if m.stateCh != nil {
defer close(m.stateCh)
}
......@@ -242,7 +248,7 @@ func (m *MasterElection) Run(stop chan bool) {
} else {
// An error of some other sort! Retry.
m.Log.Printf("unexpected error: %v", err)
time.Sleep(errorDelay)
}
}
}
// Package presence allows individual nodes in a cluster to let their
// presence known to other peers through a central registry (a
// directory on etcd). Nodes can store a small amount of information
// along with their state.
//
package presence
import (
......@@ -23,6 +28,8 @@ type Client struct {
path string
}
// NewClient returns a simple client that can look up the registry and
// return a list of active nodes.
func NewClient(client EtcdClient, path string) *Client {
return &Client{
client: client,
......@@ -58,7 +65,8 @@ type Presence struct {
}
// New returns a new Presence worker that establishes node presence at
// the specified path.
// the specified path. It will create a new unique file below that
// directory, and remove it when Stop() is called (or the TTL expires).
func New(client EtcdClient, path string, stateFn StateFn, ttl uint64) *Presence {
return &Presence{
Client: NewClient(client, path),
......
......@@ -12,6 +12,10 @@ type hasClose interface {
Close() error
}
// Cache for data that is expensive to decode. Keeps the (decoded)
// contents of the remote etcd directory in memory. Uses a DecodeFn to
// parse the encoded data stored in etcd only when it is actually
// modified.
type Cache struct {
w *Watcher
decodeFn DecodeFn
......@@ -25,6 +29,7 @@ func defaultDecodeFn(value string) interface{} {
return value
}
// NewCache returns a new Cache mirroring 'path'.
func NewCache(client EtcdClient, path string, decodeFn DecodeFn) *Cache {
if decodeFn == nil {
decodeFn = defaultDecodeFn
......@@ -44,6 +49,7 @@ func NewCache(client EtcdClient, path string, decodeFn DecodeFn) *Cache {
return c
}
// Close the Cache and release associated resources.
func (c *Cache) Close() {
c.w.Stop()
}
......@@ -90,6 +96,7 @@ func (c *Cache) handleResponse(resp *etcd.Response) {
c.lock.Unlock()
}
// Get a value from the cache.
func (c *Cache) Get(key string) (interface{}, bool) {
c.lock.RLock()
value, ok := c.data[key]
......@@ -97,6 +104,7 @@ func (c *Cache) Get(key string) (interface{}, bool) {
return value, ok
}
// Get a value and the associated etcd index.
func (c *Cache) GetWithIndex(key string) (interface{}, uint64, bool) {
c.lock.RLock()
index := c.index
......
// Package watcher monitors a path on etcd for changes, and sends them
// on a channel. It can thus build a local in-memory cache of the
// contents of the etcd directory, which is convenient for small
// datasets that don't change often (configuration data, for
// instance).
//
// The package includes both a simple cache implementation (Cache),
// and a background worker to synchronize arbitrary objects
// implementing the Syncable interface (Syncer).
//
package watcher
import (
......
#!/bin/sh
#
# Test that the running autoradio cluster on Vagrant is performing
# as expected.
#
expected_dns="192.168.50.2 192.168.50.3 192.168.50.4"
dns=$(dig +short stream.autora.dio @192.168.50.3 | sort | tr '\n' ' ' | sed -e 's/ $//')
if [ "$dns" != "$expected_dns" ]; then
echo "DNS query for stream.autora.dio did not return expected results: ${expected_dns}" >&2
exit 1
fi
echo "Vagrant autoradio cluster looks ok." >&2
exit 0
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment