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