github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/jujud/agent/engine/valueworker.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package engine 5 6 import ( 7 "reflect" 8 9 "github.com/juju/errors" 10 "gopkg.in/juju/worker.v1" 11 "gopkg.in/tomb.v2" 12 ) 13 14 // NewValueWorker returns a degenerate worker that exposes the supplied value 15 // when passed into ValueWorkerOutput. Please do not supply values that have 16 // their own dependency or lifecycle considerations; such values will subvert 17 // the operation of any containing dependency.Engine by insulating it from the 18 // failures and dependency changes of the contained value. 19 func NewValueWorker(value interface{}) (worker.Worker, error) { 20 if value == nil { 21 return nil, errors.New("NewValueWorker expects a value") 22 } 23 w := &valueWorker{ 24 value: value, 25 } 26 w.tomb.Go(func() error { 27 <-w.tomb.Dying() 28 return nil 29 }) 30 return w, nil 31 } 32 33 // ValueWorkerOutput sets the value wrapped by the supplied valueWorker into 34 // the out pointer, if type-compatible, or fails. 35 func ValueWorkerOutput(in worker.Worker, out interface{}) error { 36 inWorker, _ := in.(*valueWorker) 37 if inWorker == nil { 38 return errors.Errorf("in should be a *valueWorker; is %#v", in) 39 } 40 outV := reflect.ValueOf(out) 41 if outV.Kind() != reflect.Ptr { 42 return errors.Errorf("out should be a pointer; is %#v", out) 43 } 44 outValV := outV.Elem() 45 outValT := outValV.Type() 46 inValV := reflect.ValueOf(inWorker.value) 47 inValT := inValV.Type() 48 if !inValT.ConvertibleTo(outValT) { 49 return errors.Errorf("cannot output into %T", out) 50 } 51 outValV.Set(inValV.Convert(outValT)) 52 return nil 53 } 54 55 // valueWorker implements a degenerate worker wrapping a single value. 56 type valueWorker struct { 57 tomb tomb.Tomb 58 value interface{} 59 } 60 61 // Kill is part of the worker.Worker interface. 62 func (v *valueWorker) Kill() { 63 v.tomb.Kill(nil) 64 } 65 66 // Wait is part of the worker.Worker interface. 67 func (v *valueWorker) Wait() error { 68 return v.tomb.Wait() 69 }