github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/worker/dependency/interface.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package dependency
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  
     9  	"github.com/juju/juju/worker"
    10  )
    11  
    12  // Engine is a mechanism for persistently running named workers and managing
    13  // dependencies between them.
    14  type Engine interface {
    15  
    16  	// Install causes the Engine to accept responsibility for maintaining a
    17  	// worker corresponding to the supplied manifold, restarting it when it
    18  	// fails and when its inputs' workers change, until the Engine shuts down.
    19  	Install(name string, manifold Manifold) error
    20  
    21  	// Engine is just another Worker.
    22  	worker.Worker
    23  }
    24  
    25  // Manifold defines the behaviour of a node in an Engine's dependency graph. It's
    26  // named for the "device that connects multiple inputs or outputs" sense of the
    27  // word.
    28  type Manifold struct {
    29  
    30  	// Inputs lists the names of the manifolds which this manifold might use.
    31  	// An engine will attempt to start a worker independent of the availability
    32  	// of these inputs, and will restart the worker as the available inputs
    33  	// change. If a worker has no dependencies, it should declare empty inputs.
    34  	Inputs []string
    35  
    36  	// Start is used to create a worker for the manifold. It must not be nil.
    37  	Start StartFunc
    38  
    39  	// Output is used to implement a GetResourceFunc for manifolds that declare
    40  	// a dependency on this one; it can be nil if your manifold is a leaf node,
    41  	// or if it exposes no services to its dependents.
    42  	Output OutputFunc
    43  }
    44  
    45  // Manifolds conveniently represents several Manifolds.
    46  type Manifolds map[string]Manifold
    47  
    48  // Install is a convenience function for installing multiple manifolds into an
    49  // engine at once. It returns the first error it encounters (and installs no more
    50  // manifolds).
    51  func Install(engine Engine, manifolds Manifolds) error {
    52  	for name, manifold := range manifolds {
    53  		if err := engine.Install(name, manifold); err != nil {
    54  			return errors.Trace(err)
    55  		}
    56  	}
    57  	return nil
    58  }
    59  
    60  // StartFunc returns a worker or an error. All the worker's dependencies should
    61  // be taken from the supplied GetResourceFunc; if no worker can be started due
    62  // to unmet dependencies, it should return ErrMissing, in which case it will
    63  // not be called again until its declared inputs change.
    64  type StartFunc func(getResource GetResourceFunc) (worker.Worker, error)
    65  
    66  // GetResourceFunc returns an indication of whether a named dependency can be
    67  // satisfied. In particular:
    68  //
    69  //  * if the named resource does not exist, it returns ErrMissing
    70  //  * if the named resource exists, and out is nil, it returns nil
    71  //  * if the named resource exists, and out is non-nil, it returns the error
    72  //    from the named resource manifold's output func (hopefully nil)
    73  //
    74  // Appropriate types for the out pointer depend upon the resource in question.
    75  type GetResourceFunc func(name string, out interface{}) error
    76  
    77  // ErrMissing can be returned by a StartFunc or a worker to indicate to
    78  // the engine that it can't be usefully restarted until at least one of its
    79  // dependencies changes. There's no way to specify *which* dependency you need,
    80  // because that's a lot of implementation hassle for little practical gain.
    81  var ErrMissing = errors.New("dependency not available")
    82  
    83  // OutputFunc is a type coercion function for a worker generated by a StartFunc.
    84  // When passed an out pointer to a type it recognises, it will assign a suitable
    85  // value and return no error.
    86  type OutputFunc func(in worker.Worker, out interface{}) error
    87  
    88  // IsFatalFunc is used to configure an Engine such that, if any worker returns
    89  // an error that satisfies the engine's IsFatalFunc, the engine will stop all
    90  // its workers, shut itself down, and return the original fatal error via Wait().
    91  type IsFatalFunc func(err error) bool
    92  
    93  // MoreImportantFunc is used to determine which of two errors is more important.
    94  type MoreImportantFunc func(err0, err1 error) error