cluster

package module
v0.0.0-...-6133dcb Latest Latest
Warning

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

Go to latest
Published: Jun 28, 2013 License: Unlicense Imports: 8 Imported by: 0

README

Package cluster provides a small and simple API to manage a set of remote peers. It falls short of a distributed hash table in that the only communication allowed between two nodes is direct communication.

The central contribution of this package is to keep the set of remote peers updated and accurate. Namely, whenever a remote is added, that remote will share all of the remotes that it knows about. The result is a very simple form of peer discovery. This also includes handling both graceful and ungraceful disconnections. In particular, if a node is disconnected ungracefully, other nodes will periodically try to reconnect with it.

Documentation

http://godoc.org/github.com/BurntSushi/cluster

Installation

go get github.com/BurntSushi/cluster

Example

Here's a contrived example which creates two nodes and broadcasts a message.

package main

import (
    "fmt"
    "log"
    "github.com/BurntSushi/cluster"
)

func main() {
    // Start two nodes on a randomly chosen port.
    n1, err := cluster.New("localhost:0")
    if err != nil {
        log.Fatal(err)
    }
    
    n2, err := cluster.New("localhost:0")
    if err != nil {
        log.Fatal(err)
    }
    
    // Make the two nodes aware of each other.
    if err := n1.Add(n2.Addr().String()); err != nil {
        log.Fatalf("Could not connect node 1 to node 2: %s", err)
    }
    
    // Wait for the remote to be added and then broadcast
    // a message from node 1.
    n1.RemoteAdded(func(_ Remote) {
        n1.Broadcast([]byte("Hello, world!"))
    })
    
    // Receive the message in node 2's inbox and print.
    m := <-n2.Inbox
    fmt.Println(string(m.Payload))
}

Why?

It's possible to achieve similar functionality of this package by using a real distributed hash table, but the only one I could find written in Go was Wendy. I was not skilled enough to get it to track peers as aggressively as I wanted. Since I expressly did not want the ability to route messages through other nodes, I decided to write something simpler.

Problems

My experience with writing distributed programs is rather limited, so it's quite probable I've made some amateur mistakes. With that said, here's what I know is wrong thus far:

  • There is no protocol specified. It would be pretty easy to turn the existing implementation into a protocol, but I don't trust myself to do that. As of right now, the protocol is a simple message passing scheme using the GOB encoding.

  • I've made no considerations for DoS. I'm not sure where to start either.

Documentation

Overview

Package cluster provides a small and simple API to manage a set of remote peers. It falls short of a distributed hash table in that the only communication allowed between two nodes is direct communication.

The central contribution of this package is to keep the set of remote peers updated and accurate. Namely, whenever a remote is added, that remote will share all of the remotes that it knows about. The result is a very simple form of peer discovery. This also includes handling both graceful and ungraceful disconnections. In particular, if a node is disconnected ungracefully, other nodes will periodically try to reconnect with it.

As of now, there is no standard protocol. Messages are transmitted via GOB encoding.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Message

type Message struct {
	// The remote address of the sender.
	From Remote

	// The content of the message.
	Payload []byte
}

Message represents data sent to your node from another node. They can be retrieved via the Inbox channel of the corresponding node.

type Node

type Node struct {
	Inbox chan *Message
	// contains filtered or unexported fields
}

Node corresponds to a single local entity in a cluster. Messages sent to this node must be retrieved by reading from the Inbox channel. Note that if messages are never read, the channel buffer will fill and the Node will stop functioning until messages are drained.

There is no restriction on the number of nodes that may exist in a single program.

func New

func New(laddr string) (*Node, error)

New creates a new Node that can be used immediately. In order to communicate with other nodes, remotes must be added with the Add method.

The local address should be of the form "host:port". If the port is 0, then one will be chosen for you automatically. The chosen port can be accessed with the Addr method.

func (*Node) Add

func (n *Node) Add(raddr string) error

Add joins the node to another node at the remote address specified.

func (*Node) Addr

func (n *Node) Addr() *net.TCPAddr

Addr returns the TCP address that the node is listening on.

func (*Node) Broadcast

func (n *Node) Broadcast(data []byte)

Broadcast sends the supplied message to every remote known by this node.

func (*Node) Close

func (n *Node) Close()

Close gracefully shuts down this node from the cluster and returns only after all goroutines associated with the node have stopped. Other nodes will not attempt reconnection.

func (*Node) CloseRemote

func (n *Node) CloseRemote(r Remote)

CloseRemote gracefully closes a connection with the remote specified. No automatic reconnection will be made.

func (*Node) RemoteAdded

func (n *Node) RemoteAdded(f func(r Remote))

func (*Node) RemoteChanged

func (n *Node) RemoteChanged(f func(rs []Remote))

func (*Node) RemoteRemoved

func (n *Node) RemoteRemoved(f func(r Remote))

func (*Node) Remotes

func (n *Node) Remotes() []Remote

Remotes returns a slice of all remotes known by the node.

func (*Node) Send

func (n *Node) Send(to Remote, data []byte) error

Send sends the payload to the specified remote.

func (*Node) SetDebug

func (n *Node) SetDebug(on bool)

SetDebug, when `on` is true, will output more messages to stderr.

func (*Node) SetHealthyInterval

func (n *Node) SetHealthyInterval(d time.Duration)

SetHealthyInterval specifies how often the health of all remotes known by this node is checked. If a remote cannot receive a message, then it is ungracefully removed from known remotes. The default interval is 30 seconds.

func (*Node) SetNetworkTimeout

func (n *Node) SetNetworkTimeout(d time.Duration)

SetNetworkTimeout specifies how long a TCP send or receive will wait before timing out the connection. If a remote times out, it is ungracefully removed from known remotes. The default interval is 10 seconds.

func (*Node) SetReconnectInterval

func (n *Node) SetReconnectInterval(d time.Duration)

SetReconnectInterval specifies the interval at which reconnection is attempted with disconnected remotes. The default interval is 5 minutes.

Note that reconnection only applies to remotes that were ungracefully disconnected from the cluster. A graceful disconnection can only happen by calling Close or CloseRemote.

func (*Node) String

func (n *Node) String() string

type Remote

type Remote net.TCPAddr

func (Remote) String

func (r Remote) String() string

Jump to

Keyboard shortcuts

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