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