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 }