github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/worker/instancepoller/worker.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package instancepoller 5 6 import ( 7 "time" 8 9 "github.com/juju/errors" 10 "github.com/juju/utils/clock" 11 "gopkg.in/juju/names.v2" 12 13 "github.com/juju/juju/api/instancepoller" 14 "github.com/juju/juju/instance" 15 "github.com/juju/juju/worker" 16 "github.com/juju/juju/worker/catacomb" 17 ) 18 19 type Config struct { 20 Clock clock.Clock 21 Delay time.Duration 22 Facade *instancepoller.API 23 Environ InstanceGetter 24 } 25 26 func (config Config) Validate() error { 27 if config.Clock == nil { 28 return errors.NotValidf("nil clock.Clock") 29 } 30 if config.Delay == 0 { 31 return errors.NotValidf("zero Delay") 32 } 33 if config.Facade == nil { 34 return errors.NotValidf("nil Facade") 35 } 36 if config.Environ == nil { 37 return errors.NotValidf("nil Environ") 38 } 39 return nil 40 } 41 42 type updaterWorker struct { 43 config Config 44 aggregator *aggregator 45 catacomb catacomb.Catacomb 46 } 47 48 // NewWorker returns a worker that keeps track of 49 // the machines in the state and polls their instance 50 // addresses and status periodically to keep them up to date. 51 func NewWorker(config Config) (worker.Worker, error) { 52 if err := config.Validate(); err != nil { 53 return nil, errors.Trace(err) 54 } 55 u := &updaterWorker{ 56 config: config, 57 } 58 err := catacomb.Invoke(catacomb.Plan{ 59 Site: &u.catacomb, 60 Work: u.loop, 61 }) 62 if err != nil { 63 return nil, errors.Trace(err) 64 } 65 return u, nil 66 } 67 68 // Kill is part of the worker.Worker interface. 69 func (u *updaterWorker) Kill() { 70 u.catacomb.Kill(nil) 71 } 72 73 // Wait is part of the worker.Worker interface. 74 func (u *updaterWorker) Wait() error { 75 return u.catacomb.Wait() 76 } 77 78 func (u *updaterWorker) loop() (err error) { 79 u.aggregator, err = newAggregator( 80 aggregatorConfig{ 81 Clock: u.config.Clock, 82 Delay: u.config.Delay, 83 Environ: u.config.Environ, 84 }, 85 ) 86 if err != nil { 87 return errors.Trace(err) 88 } 89 if err := u.catacomb.Add(u.aggregator); err != nil { 90 return errors.Trace(err) 91 } 92 watcher, err := u.config.Facade.WatchModelMachines() 93 if err != nil { 94 return errors.Trace(err) 95 } 96 if err := u.catacomb.Add(watcher); err != nil { 97 return errors.Trace(err) 98 } 99 return watchMachinesLoop(u, watcher) 100 } 101 102 // newMachineContext is part of the updaterContext interface. 103 func (u *updaterWorker) newMachineContext() machineContext { 104 return u 105 } 106 107 // getMachine is part of the machineContext interface. 108 func (u *updaterWorker) getMachine(tag names.MachineTag) (machine, error) { 109 return u.config.Facade.Machine(tag) 110 } 111 112 // instanceInfo is part of the machineContext interface. 113 func (u *updaterWorker) instanceInfo(id instance.Id) (instanceInfo, error) { 114 return u.aggregator.instanceInfo(id) 115 } 116 117 // kill is part of the lifetimeContext interface. 118 func (u *updaterWorker) kill(err error) { 119 u.catacomb.Kill(err) 120 } 121 122 // dying is part of the lifetimeContext interface. 123 func (u *updaterWorker) dying() <-chan struct{} { 124 return u.catacomb.Dying() 125 } 126 127 // errDying is part of the lifetimeContext interface. 128 func (u *updaterWorker) errDying() error { 129 return u.catacomb.ErrDying() 130 }