Documentation ¶
Overview ¶
relation implements persistent local storage of a unit's relation state, and translation of relation changes into hooks that need to be run.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type HookQueue ¶
type HookQueue interface { HookSender }
HookQueue exists to keep the package interface stable.
func NewAliveHookQueue ¶
func NewAliveHookQueue(initial *State, out chan<- hook.Info, w RelationUnitsWatcher) HookQueue
NewAliveHookQueue exists to keep the package interface stable; it wraps the result of NewLiveHookSource in a HookSender.
type HookSender ¶
type HookSender interface {
Stop() error
}
HookSender maintains a HookSource and delivers its hooks via a channel.
func NewHookSender ¶
func NewHookSender(out chan<- hook.Info, source HookSource) HookSender
NewHookSender starts sending hooks from source onto the out channel, and will continue to do so until Stop()ped (or the source is exhausted). NewHookSender takes ownership of the supplied source, and responsibility for cleaning it up; but it will not close the out channel.
type HookSource ¶
type HookSource interface { // Changes returns a channel sending events which must be delivered -- // synchronously, and in order -- to the HookSource's Update method . Changes() <-chan multiwatcher.RelationUnitsChange // Stop causes the HookSource to clean up its resources and stop sending // changes. Stop() error // Update applies the supplied change to the HookSource's schedule, and // invalidates the results of previous calls to Next() and Empty(). It // should only be called with change events received from the Changes() // channel. Update(change multiwatcher.RelationUnitsChange) error // Empty returns false if any hooks are scheduled. Empty() bool // Next returns the first scheduled hook. It will panic if no hooks are // scheduled. Next() hook.Info // Pop removes the first scheduled hook, and invalidates the results of // previous calls to Next() and Empty(). It will panic if no hooks are // scheduled. Pop() }
HookSource defines a generator of hook.Info events. A HookSource's client must be careful to:
- use it from a single goroutine.
- collect asynchronous events from Changes(), and synchronously pass them to Update() whenever possible.
- only use fresh values returned from Empty() and Next(); i.e. only those which have been generated since the last call to Pop() or Update().
- Stop() it when finished.
func NewDyingHookSource ¶
func NewDyingHookSource(initial *State) HookSource
NewDyingHookSource returns a new HookSource that generates all hooks necessary to clean up the supplied initial relation hook state, while preserving the guarantees Juju makes about hook execution order.
func NewListSource ¶
func NewListSource(list []hook.Info) HookSource
NewListSource returns a HookSource that generates only the supplied hooks, in order; and which cannot be updated.
func NewLiveHookSource ¶
func NewLiveHookSource(initial *State, w RelationUnitsWatcher) HookSource
NewLiveHookSource returns a new HookSource that aggregates the values obtained from the w watcher and generates the hooks that must be executed in the unit. It guarantees that the stream of hooks will respect the guarantees Juju makes about hook execution order. If any values have previously been received from w's Changes channel, the HookSource's behaviour is undefined.
type NoUpdates ¶
type NoUpdates struct{}
NoUpdates implements a subset of HookSource that delivers no changes, errors on update, and ignores stop requests (because there's nothing running in the first place). It's useful for implementing static HookSources.
func (*NoUpdates) Changes ¶
func (_ *NoUpdates) Changes() <-chan multiwatcher.RelationUnitsChange
func (*NoUpdates) Update ¶
func (_ *NoUpdates) Update(_ multiwatcher.RelationUnitsChange) error
type Peek ¶
type Peek interface { // HookInfo returns information about the hook at the head of the queue. HookInfo() hook.Info // Consume pops the hook from the head of the queue and makes new Peeks // available. Consume() // Reject makes new Peeks available. Reject() }
Peek exists to support Peeker and has no independent meaning or existence. Receiving a Peek from a Peeker's Peek channel implies acceptance of the responsibility to either Consume or Reject the Peek.
type Peeker ¶
type Peeker interface { // Peeks returns a channel on which Peeks are delivered. The receiver of a // Peek must Consume or Reject the Peek before further peeks will be sent. Peeks() <-chan Peek // Stop stops the Peeker's HookSource, and prevents any further Peeks from // being delivered. Stop() error }
Peeker maintains a HookSource, and allows an external client to inspect and consume, or reject, the head of the queue.
func NewPeeker ¶
func NewPeeker(source HookSource) Peeker
NewPeeker returns a new Peeker providing a view of the supplied source (of which it takes ownership).
type RelationUnitsWatcher ¶
type RelationUnitsWatcher interface { Err() error Stop() error Changes() <-chan multiwatcher.RelationUnitsChange }
RelationUnitsWatcher produces RelationUnitsChange events until stopped, or until it encounters an error. It must not close its Changes channel without signalling an error via Stop and Err.
type State ¶
type State struct { // RelationId identifies the relation. RelationId int // Members is a map from unit name to the last change version // for which a hook.Info was delivered on the output channel. Members map[string]int64 // ChangedPending indicates that a "relation-changed" hook for the given // unit name must be the first hook.Info to be sent to the output channel. ChangedPending string }
State describes the state of a relation.
type StateDir ¶
type StateDir struct {
// contains filtered or unexported fields
}
StateDir is a filesystem-backed representation of the state of a relation. Concurrent modifications to the underlying state directory will have undefined consequences.
func ReadStateDir ¶
ReadStateDir loads a StateDir from the subdirectory of dirPath named for the supplied RelationId. If the directory does not exist, no error is returned,