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