github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/worker/uniter/remotestate/relationunits.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package remotestate
     5  
     6  import (
     7  	"launchpad.net/tomb"
     8  
     9  	apiwatcher "github.com/juju/juju/api/watcher"
    10  	"github.com/juju/juju/state/multiwatcher"
    11  	"github.com/juju/juju/state/watcher"
    12  )
    13  
    14  type relationUnitsWatcher struct {
    15  	tomb       tomb.Tomb
    16  	relationId int
    17  	in         apiwatcher.RelationUnitsWatcher
    18  	out        chan<- relationUnitsChange
    19  }
    20  
    21  type relationUnitsChange struct {
    22  	relationId int
    23  	multiwatcher.RelationUnitsChange
    24  }
    25  
    26  func newRelationUnitsWatcher(
    27  	relationId int,
    28  	in apiwatcher.RelationUnitsWatcher,
    29  	out chan<- relationUnitsChange,
    30  ) *relationUnitsWatcher {
    31  	ruw := &relationUnitsWatcher{relationId: relationId, in: in, out: out}
    32  	go func() {
    33  		defer ruw.tomb.Done()
    34  		// TODO(axw) add Kill() and Wait() to watchers?
    35  		//
    36  		// At the moment we have to rely on the watcher's
    37  		// channel being closed inside loop() to react
    38  		// to it being killed/stopped.
    39  		ruw.tomb.Kill(ruw.loop())
    40  		ruw.tomb.Kill(in.Stop())
    41  	}()
    42  	return ruw
    43  }
    44  
    45  func (w *relationUnitsWatcher) Stop() error {
    46  	w.tomb.Kill(nil)
    47  	return w.tomb.Wait()
    48  }
    49  
    50  func (w *relationUnitsWatcher) loop() error {
    51  	for {
    52  		select {
    53  		case <-w.tomb.Dying():
    54  			return tomb.ErrDying
    55  		case change, ok := <-w.in.Changes():
    56  			if !ok {
    57  				return watcher.EnsureErr(w.in)
    58  			}
    59  			select {
    60  			case <-w.tomb.Dying():
    61  				return tomb.ErrDying
    62  			case w.out <- relationUnitsChange{w.relationId, change}:
    63  			}
    64  		}
    65  	}
    66  	return nil
    67  }