github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/remoterelations/remoterelationsworker.go (about)

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package remoterelations
     5  
     6  import (
     7  	"gopkg.in/juju/names.v2"
     8  	"gopkg.in/juju/worker.v1"
     9  	"gopkg.in/juju/worker.v1/catacomb"
    10  
    11  	"github.com/juju/juju/apiserver/params"
    12  	"github.com/juju/juju/core/watcher"
    13  )
    14  
    15  // remoteRelationsWorker listens for changes to the
    16  // life and status of a relation in the offering model.
    17  type remoteRelationsWorker struct {
    18  	catacomb catacomb.Catacomb
    19  
    20  	relationTag         names.RelationTag
    21  	remoteRelationToken string
    22  	applicationToken    string
    23  	relationsWatcher    watcher.RelationStatusWatcher
    24  	changes             chan<- params.RemoteRelationChangeEvent
    25  }
    26  
    27  func newRemoteRelationsWorker(
    28  	relationTag names.RelationTag,
    29  	applicationToken string,
    30  	remoteRelationToken string,
    31  	relationsWatcher watcher.RelationStatusWatcher,
    32  	changes chan<- params.RemoteRelationChangeEvent,
    33  ) (*remoteRelationsWorker, error) {
    34  	w := &remoteRelationsWorker{
    35  		relationsWatcher:    relationsWatcher,
    36  		relationTag:         relationTag,
    37  		remoteRelationToken: remoteRelationToken,
    38  		applicationToken:    applicationToken,
    39  		changes:             changes,
    40  	}
    41  	err := catacomb.Invoke(catacomb.Plan{
    42  		Site: &w.catacomb,
    43  		Work: w.loop,
    44  		Init: []worker.Worker{relationsWatcher},
    45  	})
    46  	return w, err
    47  }
    48  
    49  // Kill is defined on worker.Worker
    50  func (w *remoteRelationsWorker) Kill() {
    51  	w.catacomb.Kill(nil)
    52  }
    53  
    54  // Wait is defined on worker.Worker
    55  func (w *remoteRelationsWorker) Wait() error {
    56  	return w.catacomb.Wait()
    57  }
    58  
    59  func (w *remoteRelationsWorker) loop() error {
    60  	var (
    61  		changes chan<- params.RemoteRelationChangeEvent
    62  		event   params.RemoteRelationChangeEvent
    63  	)
    64  	for {
    65  		select {
    66  		case <-w.catacomb.Dying():
    67  			return w.catacomb.ErrDying()
    68  
    69  		case relChanges, ok := <-w.relationsWatcher.Changes():
    70  			if !ok {
    71  				// We are dying.
    72  				return w.catacomb.ErrDying()
    73  			}
    74  			if len(relChanges) == 0 {
    75  				logger.Warningf("relation status watcher event with no changes")
    76  				continue
    77  			}
    78  			// We only care about the most recent change.
    79  			change := relChanges[len(relChanges)-1]
    80  			logger.Debugf("relation status changed for %v: %v", w.relationTag, change)
    81  			suspended := change.Suspended
    82  			event = params.RemoteRelationChangeEvent{
    83  				RelationToken:    w.remoteRelationToken,
    84  				ApplicationToken: w.applicationToken,
    85  				Life:             params.Life(change.Life),
    86  				Suspended:        &suspended,
    87  				SuspendedReason:  change.SuspendedReason,
    88  			}
    89  			changes = w.changes
    90  
    91  		case changes <- event:
    92  			changes = nil
    93  		}
    94  	}
    95  }