github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/apiserver/common/modelmachineswatcher.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package common 5 6 import ( 7 "fmt" 8 "time" 9 10 apiservererrors "github.com/juju/juju/apiserver/errors" 11 "github.com/juju/juju/apiserver/facade" 12 "github.com/juju/juju/rpc/params" 13 "github.com/juju/juju/state" 14 "github.com/juju/juju/state/watcher" 15 ) 16 17 // watchMachinesQuiesceInterval specifies the time window for batching together 18 // changes to life and agent start times when watching the machine collection 19 // for a particular model. For more information, see the WatchModelMachineStartTimes 20 // method in state/watcher.go. 21 const watchMachinesQuiesceInterval = 500 * time.Millisecond 22 23 // ModelMachinesWatcher implements a common WatchModelMachines 24 // method for use by various facades. 25 type ModelMachinesWatcher struct { 26 st state.ModelMachinesWatcher 27 resources facade.Resources 28 authorizer facade.Authorizer 29 } 30 31 // NewModelMachinesWatcher returns a new ModelMachinesWatcher. The 32 // GetAuthFunc will be used on each invocation of WatchUnits to 33 // determine current permissions. 34 func NewModelMachinesWatcher(st state.ModelMachinesWatcher, resources facade.Resources, authorizer facade.Authorizer) *ModelMachinesWatcher { 35 return &ModelMachinesWatcher{ 36 st: st, 37 resources: resources, 38 authorizer: authorizer, 39 } 40 } 41 42 // WatchModelMachines returns a StringsWatcher that notifies of 43 // changes to the life cycles of the top level machines in the current 44 // model. 45 func (e *ModelMachinesWatcher) WatchModelMachines() (params.StringsWatchResult, error) { 46 result := params.StringsWatchResult{} 47 if !e.authorizer.AuthController() { 48 return result, apiservererrors.ErrPerm 49 } 50 watch := e.st.WatchModelMachines() 51 // Consume the initial event and forward it to the result. 52 if changes, ok := <-watch.Changes(); ok { 53 result.StringsWatcherId = e.resources.Register(watch) 54 result.Changes = changes 55 } else { 56 err := watcher.EnsureErr(watch) 57 return result, fmt.Errorf("cannot obtain initial model machines: %v", err) 58 } 59 return result, nil 60 } 61 62 // WatchModelMachineStartTimes watches the non-container machines in the model 63 // for changes to the Life or AgentStartTime fields and reports them as a batch. 64 func (e *ModelMachinesWatcher) WatchModelMachineStartTimes() (params.StringsWatchResult, error) { 65 result := params.StringsWatchResult{} 66 if !e.authorizer.AuthController() { 67 return result, apiservererrors.ErrPerm 68 } 69 watch := e.st.WatchModelMachineStartTimes(watchMachinesQuiesceInterval) 70 // Consume the initial event and forward it to the result. 71 if changes, ok := <-watch.Changes(); ok { 72 result.StringsWatcherId = e.resources.Register(watch) 73 result.Changes = changes 74 } else { 75 err := watcher.EnsureErr(watch) 76 return result, fmt.Errorf("cannot obtain initial model machines: %v", err) 77 } 78 return result, nil 79 }