liuhaijun 3f5f28d785 add sheduling agent
Change-Id: I89f35fb3984044c57f10727432755012542f9fd8
2023-11-16 10:55:57 +00:00

56 lines
955 B
Go

package utility
import (
"errors"
"reflect"
"sync"
)
type Lazy interface {
Value(value interface{}) (err error)
}
var (
TypeMismatched = errors.New("type mismatched")
)
type lazy struct {
lock *sync.Once
fetch func() (value interface{}, err error)
value interface{}
done bool
}
func (l *lazy) Value(value interface{}) (err error) {
if l.done {
l.setValueTo(value)
return
}
l.lock.Do(func() {
if l.value, err = l.fetch(); err != nil {
l.lock = new(sync.Once)
return
} else {
l.setValueTo(value)
l.done = true
}
})
return
}
func (l lazy) setValueTo(receiver interface{}) (err error) {
rv := reflect.Indirect(reflect.ValueOf(receiver))
vv := reflect.ValueOf(l.value)
if vv.Type().AssignableTo(rv.Type()) && rv.CanSet() {
rv.Set(reflect.ValueOf(l.value))
}
return TypeMismatched
}
func NewLazy(fetch func() (value interface{}, err error)) Lazy {
return &lazy{
lock: new(sync.Once),
fetch: fetch,
}
}