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  }