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