github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/worker/retrystrategy/worker.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Copyright 2016 Cloudbase Solutions 3 // Licensed under the AGPLv3, see LICENCE file for details. 4 5 package retrystrategy 6 7 import ( 8 "github.com/juju/errors" 9 "github.com/juju/names/v5" 10 "github.com/juju/worker/v3" 11 "github.com/juju/worker/v3/dependency" 12 13 "github.com/juju/juju/core/watcher" 14 "github.com/juju/juju/rpc/params" 15 ) 16 17 // Facade defines the capabilities required by the worker from the API. 18 type Facade interface { 19 RetryStrategy(names.Tag) (params.RetryStrategy, error) 20 WatchRetryStrategy(names.Tag) (watcher.NotifyWatcher, error) 21 } 22 23 // WorkerConfig defines the worker's dependencies. 24 type WorkerConfig struct { 25 Facade Facade 26 AgentTag names.Tag 27 RetryStrategy params.RetryStrategy 28 Logger Logger 29 } 30 31 // Validate returns an error if the configuration is not complete. 32 func (c WorkerConfig) Validate() error { 33 if c.Facade == nil { 34 return errors.NotValidf("nil Facade") 35 } 36 if c.AgentTag == nil { 37 return errors.NotValidf("nil AgentTag") 38 } 39 empty := params.RetryStrategy{} 40 if c.RetryStrategy == empty { 41 return errors.NotValidf("empty RetryStrategy") 42 } 43 return nil 44 } 45 46 // RetryStrategyWorker is a NotifyWorker with one additional 47 // method that returns the current retry strategy. 48 type RetryStrategyWorker struct { 49 *watcher.NotifyWorker 50 retryStrategy params.RetryStrategy 51 } 52 53 // NewRetryStrategyWorker returns a worker.Worker that returns the current 54 // retry strategy and bounces when it changes. 55 func NewRetryStrategyWorker(config WorkerConfig) (worker.Worker, error) { 56 if err := config.Validate(); err != nil { 57 return nil, errors.Trace(err) 58 } 59 w, err := watcher.NewNotifyWorker(watcher.NotifyConfig{ 60 Handler: retryStrategyHandler{config}, 61 }) 62 if err != nil { 63 return nil, errors.Trace(err) 64 } 65 return &RetryStrategyWorker{w, config.RetryStrategy}, nil 66 } 67 68 // GetRetryStrategy returns the current hook retry strategy 69 func (w *RetryStrategyWorker) GetRetryStrategy() params.RetryStrategy { 70 return w.retryStrategy 71 } 72 73 // retryStrategyHandler implements watcher.NotifyHandler 74 type retryStrategyHandler struct { 75 config WorkerConfig 76 } 77 78 // SetUp is part of the watcher.NotifyHandler interface. 79 func (h retryStrategyHandler) SetUp() (watcher.NotifyWatcher, error) { 80 return h.config.Facade.WatchRetryStrategy(h.config.AgentTag) 81 } 82 83 // Handle is part of the watcher.NotifyHandler interface. 84 // Whenever a valid change is encountered the worker bounces, 85 // making the dependents bounce and get the new value 86 func (h retryStrategyHandler) Handle(_ <-chan struct{}) error { 87 newRetryStrategy, err := h.config.Facade.RetryStrategy(h.config.AgentTag) 88 if err != nil { 89 return errors.Trace(err) 90 } 91 if newRetryStrategy != h.config.RetryStrategy { 92 h.config.Logger.Debugf("bouncing retrystrategy worker to get new values") 93 return dependency.ErrBounce 94 } 95 return nil 96 } 97 98 // TearDown is part of the watcher.NotifyHandler interface. 99 func (h retryStrategyHandler) TearDown() error { 100 // Nothing to cleanup, only state is the watcher 101 return nil 102 }