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 }