github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/worker/pruner/worker.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package pruner
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/juju/clock"
    10  	"github.com/juju/errors"
    11  	"github.com/juju/worker/v3/catacomb"
    12  
    13  	"github.com/juju/juju/core/watcher"
    14  	"github.com/juju/juju/environs/config"
    15  )
    16  
    17  // logger is here to stop the desire of creating a package level logger.
    18  // Don't do this, instead pass one through as config to the worker.
    19  type logger interface{}
    20  
    21  var (
    22  	_ logger = struct{}{}
    23  )
    24  
    25  //go:generate go run go.uber.org/mock/mockgen -package mocks -destination mocks/mocks_facade.go github.com/juju/juju/worker/pruner Facade
    26  
    27  // Facade represents an API that implements status history pruning.
    28  type Facade interface {
    29  	Prune(time.Duration, int) error
    30  	WatchForModelConfigChanges() (watcher.NotifyWatcher, error)
    31  	ModelConfig() (*config.Config, error)
    32  }
    33  
    34  // PrunerWorker prunes status history or action records at regular intervals.
    35  type PrunerWorker struct {
    36  	catacomb catacomb.Catacomb
    37  	config   Config
    38  }
    39  
    40  // Kill is defined on worker.Worker.
    41  func (w *PrunerWorker) Kill() {
    42  	w.catacomb.Kill(nil)
    43  }
    44  
    45  // Wait is defined on worker.Worker.
    46  func (w *PrunerWorker) Wait() error {
    47  	return w.catacomb.Wait()
    48  }
    49  
    50  // Catacomb returns the prune worker's catacomb.
    51  func (w *PrunerWorker) Catacomb() *catacomb.Catacomb {
    52  	return &w.catacomb
    53  }
    54  
    55  // Config return the prune worker's config.
    56  func (w *PrunerWorker) Config() *Config {
    57  	return &w.config
    58  }
    59  
    60  // Work is the main body of generic pruner loop.
    61  func (w *PrunerWorker) Work(getPrunerConfig func(*config.Config) (time.Duration, uint)) error {
    62  	modelConfigWatcher, err := w.config.Facade.WatchForModelConfigChanges()
    63  	if err != nil {
    64  		return errors.Trace(err)
    65  	}
    66  	err = w.catacomb.Add(modelConfigWatcher)
    67  	if err != nil {
    68  		return errors.Trace(err)
    69  	}
    70  
    71  	var (
    72  		maxAge             time.Duration
    73  		maxCollectionMB    uint
    74  		modelConfigChanges = modelConfigWatcher.Changes()
    75  		// We will also get an initial event, but need to ensure that event is
    76  		// received before doing any pruning.
    77  	)
    78  
    79  	var timer clock.Timer
    80  	var timerCh <-chan time.Time
    81  	for {
    82  		select {
    83  		case <-w.catacomb.Dying():
    84  			return w.catacomb.ErrDying()
    85  
    86  		case _, ok := <-modelConfigChanges:
    87  			if !ok {
    88  				return errors.New("model configuration watcher closed")
    89  			}
    90  			modelConfig, err := w.config.Facade.ModelConfig()
    91  			if err != nil {
    92  				return errors.Annotate(err, "cannot load model configuration")
    93  			}
    94  
    95  			newMaxAge, newMaxCollectionMB := getPrunerConfig(modelConfig)
    96  
    97  			if newMaxAge != maxAge || newMaxCollectionMB != maxCollectionMB {
    98  				w.config.Logger.Infof("pruner config: max age: %v, max collection size %dM for %s (%s)",
    99  					newMaxAge, newMaxCollectionMB, modelConfig.Name(), modelConfig.UUID())
   100  				maxAge = newMaxAge
   101  				maxCollectionMB = newMaxCollectionMB
   102  			}
   103  			if timer == nil {
   104  				timer = w.config.Clock.NewTimer(w.config.PruneInterval)
   105  				timerCh = timer.Chan()
   106  			}
   107  
   108  		case <-timerCh:
   109  			err := w.config.Facade.Prune(maxAge, int(maxCollectionMB))
   110  			if err != nil {
   111  				return errors.Trace(err)
   112  			}
   113  			timer.Reset(w.config.PruneInterval)
   114  		}
   115  	}
   116  }