Circuit Self-managed infrastructure, programmatic monitoring and orchestration

Go client API

To use the Go client API to the circuit, start by importing the client package:

	import "github.com/gocircuit/circuit/client"

System abstraction

The circuit organizes all of the cluster resources in an abstract hierarchichal namespace—a rooted tree with named edges. Every node in the tree is called an anchor and every anchor is associated with the root-to-anchor path that leads to it. A path identifies its anchor uniquely. In file system notation, paths are strings like "/Xf1c8d96119cc6919/foo/bar".

In addition to being a tree node in the namespace, each anchor can have none or one element attached to it. An element is a logical object that manages an underlying computational resource. There are different kinds of elements, according to their underlying resource: process, container, name server, channel, etc.

Virtual anchor hierarchy, depicting elements attached to some of the anchors.

The Go client interface is organized around the anchor hierarchy abstraction.

An interface called Anchor represents an anchor. It provides methods for traversing and inspecting its descendant anchors, as well as methods for creating or retrieving the element associated it.

All circuit applications begin with a call to Dial (or DialDiscover) which establishes connection to a circuit cluster and returns an Anchor object representing the root of the hierarchy. (Programming details for connecting into a cluster are given below.)

Anchor and element residence

Every anchor—excluding the root anchor—as well as its attached element (if any) physically reside on some specific host in the circuit cluster. (The Anchor and element objects in a Go client application are merely references to the underlying anchor and element structures.)

The following illustration demonstrates how the hierarchy structure implies the physical location of anchors and elements.

Except for the root, every anchor physically resides on some circuit host. The root anchor is a logical object representing your client's connection to the cluster.

The root anchor (which you obtain from Dial or DialDiscover) is special. It symbolically represents your client's connection to the circuit cluster. As such, the root anchor resides only in your client's runtime—i.e. it is not persistent. No elements can be attached to the root anchor.

The children of the root anchor are always, by definition, server anchors. Server anchors correspond to currently live hosts (aka servers) in your circuit cluster. Server anchors are created and removed by the circuit system, as hosts join or leave the circuit cluster.

Server anchors physically reside on their respective host and they have an attached Server element that allows you to query various runtime parameters of the host. Server elements are permanently attached to their anchors.

All anchors descendant to server anchors, and their attached elements, are created by the user. All such user anchors as well as the elements that might be attached to them reside—by definition—on the host of the server anchor that they descend from.

Panics and errors

All programmatic manipulation of a circuit client involves calling methods of Anchor or element objects. As we discussed, all anchors and elements have an implied physical place of residence (on one of the cluster hosts).

In general, any method invokation might result in one of two types of errors: application errors and system errors.

Application errors are things like trying to create an element on anchor that already has one, or trying to start a process using a missing binary, for instance. Such errors will be returned in the form of Go error return values of the respective method.

Independently of application errors, every invokation of an anchor or element method may fail if the underlying object is physically unreachable. Anchors residing on a dead host are unreachable and so are their elements, for example. Such errors are treated in a separate category of system errors and they are reported as panics. In particular, if a host is unreachable, all anchors descendant to and including its server anchor will cause panics when used.

By design, any anchor or element method invokation will result in a panic, if a system error occurs. We uniformly report system errors as panics in order to separate them semantically from application errors. But also because they have asynchronous nature and because they usually result in a very different way of being handled by the application programmer.

That said, such panic conditions are not critical. These panics merely indicate that the host where an anchor or element physically resides is currently unreachable. The underlying host can be unreachable either if dead or as the result of a complete network partition (partial partitions do not affect the system).

An anchor or element object that produces a panic remains in a valid state after the panic and it can be re-used. If the underlying resource is still unreachable, another panic will be produced. But if the system has recovered from a network partition and the underlying resource is reachable again, follow on method calls will succeed.

Connection panics

Panics in any method invocation can also be caused if the client's connection to a circuit server is lost. This type of panic is permanent, as the circuit client does not attempt automatic reconnection to the circuit cluster.

There is a way to distinguish between host-only panics and permanent client connection panics. After catching a panic anywhere, the user application can simply call the root anchor's View method (which lists the contents of the anchor). If this call also results in a panic, this is an indication that the client connection has been lost altogether.