github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facades/agent/provisioner/machineerror.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package provisioner 5 6 import ( 7 "time" 8 9 "gopkg.in/tomb.v2" 10 11 "github.com/juju/juju/state" 12 ) 13 14 // machineErrorRetry is a notify watcher that fires when it is 15 // appropriate to retry provisioning machines with transient errors. 16 type machineErrorRetry struct { 17 tomb tomb.Tomb 18 out chan struct{} 19 } 20 21 func newWatchMachineErrorRetry() state.NotifyWatcher { 22 w := &machineErrorRetry{ 23 out: make(chan struct{}), 24 } 25 w.tomb.Go(func() error { 26 defer close(w.out) 27 return w.loop() 28 }) 29 return w 30 } 31 32 // Stop stops the watcher, and returns any error encountered while running 33 // or shutting down. 34 func (w *machineErrorRetry) Stop() error { 35 w.Kill() 36 return w.Wait() 37 } 38 39 // Kill kills the watcher without waiting for it to shut down. 40 func (w *machineErrorRetry) Kill() { 41 w.tomb.Kill(nil) 42 } 43 44 // Wait waits for the watcher to die and returns any 45 // error encountered when it was running. 46 func (w *machineErrorRetry) Wait() error { 47 return w.tomb.Wait() 48 } 49 50 // Err returns any error encountered while running or shutting down, or 51 // tomb.ErrStillAlive if the watcher is still running. 52 func (w *machineErrorRetry) Err() error { 53 return w.tomb.Err() 54 } 55 56 // Changes returns the event channel for the machineErrorRetry watcher. 57 func (w *machineErrorRetry) Changes() <-chan struct{} { 58 return w.out 59 } 60 61 // ErrorRetryWaitDelay is the poll time currently used to trigger the watcher. 62 var ErrorRetryWaitDelay = 1 * time.Minute 63 64 // The initial implementation of this watcher simply acts as a poller, 65 // triggering every ErrorRetryWaitDelay minutes. 66 func (w *machineErrorRetry) loop() error { 67 out := w.out 68 for { 69 select { 70 case <-w.tomb.Dying(): 71 return tomb.ErrDying 72 // TODO(fwereade): 2016-03-17 lp:1558657 73 case <-time.After(ErrorRetryWaitDelay): 74 out = w.out 75 case out <- struct{}{}: 76 out = nil 77 } 78 } 79 }