func (rw *RefWatch) Watch(ctx context.Context, o *onion.Onion) <-chan struct{} {
	rw.watchLoop(o)
	w := make(chan struct{})
	go func() {
		for {
			ch := o.ReloadWatch()
			select {
			case <-ctx.Done():
				return
			case <-ch:
				rw.watchLoop(o)
				select {
				case w <- struct{}{}:
				default:
				}
			}
		}
	}()
	return w
}
Watch get an onion and watch over it for changes in the layers.
package configwatch
import (
	"context"
	"sync"
	"time"
	"github.com/goraz/onion"
)
var (
	w = RefWatch{}
)
type variable struct {
	key string
	ref interface{}
	def interface{}
}
type RefWatch struct {
	refLock    sync.RWMutex
	references []variable
}
func (rw *RefWatch) addRef(key string, ref interface{}, def interface{}) {
	rw.refLock.Lock()
	defer rw.refLock.Unlock()
	rw.references = append(rw.references, variable{key: key, ref: ref, def: def})
}
func (rw *RefWatch) RegisterInt(key string, def int) Int {
	var v = int64(def)
	rw.addRef(key, &v, def)
	return intHolder{value: &v}
}
func RegisterInt(key string, def int) Int {
	return w.RegisterInt(key, def)
}
func (rw *RefWatch) RegisterInt64(key string, def int64) Int {
	var v = def
	rw.addRef(key, &v, def)
	return intHolder{value: &v}
}
func RegisterInt64(key string, def int64) Int {
	return w.RegisterInt64(key, def)
}
func (rw *RefWatch) RegisterString(key string, def string) String {
	var v = def
	rw.addRef(key, &v, def)
	return stringHolder{value: &v}
}
func RegisterString(key string, def string) String {
	return w.RegisterString(key, def)
}
func (rw *RefWatch) RegisterFloat64(key string, def float64) Float {
	var v = def
	rw.addRef(key, &v, def)
	return floatHolder{value: &v}
}
func RegisterFloat64(key string, def float64) Float {
	return w.RegisterFloat64(key, def)
}
func (rw *RefWatch) RegisterFloat32(key string, def float32) Float {
	var v = float64(def)
	rw.addRef(key, &v, def)
	return floatHolder{value: &v}
}
func RegisterFloat32(key string, def float32) Float {
	return w.RegisterFloat32(key, def)
}
func (rw *RefWatch) RegisterBool(key string, def bool) Bool {
	var v = def
	rw.addRef(key, &v, def)
	return boolHolder{value: &v}
}
func RegisterBool(key string, def bool) Bool {
	return w.RegisterBool(key, def)
}
func (rw *RefWatch) RegisterDuration(key string, def time.Duration) Int {
	var v = int64(def)
	rw.addRef(key, &v, def)
	return intHolder{value: &v}
}
func RegisterDuration(key string, def time.Duration) Int {
	return w.RegisterDuration(key, def)
}
func (rw *RefWatch) watchLoop(o *onion.Onion) {
	rw.refLock.RLock()
	globalLock.Lock()
	for i := range rw.references {
		switch def := rw.references[i].def.(type) {
		case int:
			v := o.GetInt64Default(rw.references[i].key, int64(def))
			t := rw.references[i].ref.(*int64)
			*t = v
		case int64:
			v := o.GetInt64Default(rw.references[i].key, def)
			t := rw.references[i].ref.(*int64)
			*t = v
		case string:
			v := o.GetStringDefault(rw.references[i].key, def)
			t := rw.references[i].ref.(*string)
			*t = v
		case float32:
			v := o.GetFloat64Default(rw.references[i].key, float64(def))
			t := rw.references[i].ref.(*float64)
			*t = v
		case float64:
			v := o.GetFloat64Default(rw.references[i].key, def)
			t := rw.references[i].ref.(*float64)
			*t = v
		case bool:
			v := o.GetBoolDefault(rw.references[i].key, def)
			t := rw.references[i].ref.(*bool)
			*t = v
		case time.Duration:
			v := o.GetDurationDefault(rw.references[i].key, def)
			t := rw.references[i].ref.(*int64)
			*t = int64(v)
		}
	}
	rw.refLock.RUnlock()
	globalLock.Unlock()
}