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  }