svalue/value.go
huangsimin 246235c1f9 v1.0.1
2019-01-24 14:45:59 +08:00

148 lines
2.7 KiB
Go

package svalue
import (
"errors"
"log"
"reflect"
"runtime"
"sync"
"time"
)
// IValue 必须实现的值接口
type IValue interface {
// TakeValue 获取 value的方法覆盖
TakeValue() interface{}
// 每次 TakeValue 休眠的时间
UpdateInterval() time.Duration
// Lock value的锁
Lock()
// Unlock value的解锁
Unlock()
// SetValue 设置动态的值 TakeValue 调用.
SetValue(v interface{})
// CloseSync 关闭同步
CloseSync()
// IsCloseSync 判断是否要关闭同步. 非使用者调用
IsCloseSync() bool
// SetSync 设置是否已经同步的信息. 非使用者调用
SetSync(is bool)
// IsSync 设置是否已经同步的信息. 非使用者调用
IsSync() bool
}
// Value 必须设置的动态类型
type Value struct {
IValue
value interface{}
mutex sync.Mutex
isClose bool
isSync bool
}
// SetValue 设置动态的值 TakeValue 调用
func (value *Value) SetValue(v interface{}) {
value.value = v
}
// Lock value的锁
func (value *Value) Lock() {
value.mutex.Lock()
}
// Unlock value的解锁
func (value *Value) Unlock() {
value.mutex.Unlock()
}
// IsSync 设置是否已经同步的信息. 非使用者调用
func (value *Value) IsSync() bool {
return value.isSync
}
// SetSync 设置是否已经同步的信息. 非使用者调用
func (value *Value) SetSync(is bool) {
value.isSync = is
}
// GetValue 获取value. 带并发锁
func (value *Value) GetValue() interface{} {
value.mutex.Lock()
defer value.mutex.Unlock()
return value.value
}
// CloseSync 关闭同步
func (value *Value) CloseSync() {
value.mutex.Lock()
defer value.mutex.Unlock()
value.isClose = true
}
// IsCloseSync 判断是否要关闭同步. 非使用者调用
func (value *Value) IsCloseSync() bool {
return value.isClose
}
// UpdateInterval 每次 TakeValue 休眠的时间. 可覆盖
func (value *Value) UpdateInterval() time.Duration {
return time.Second * 5
}
// StartSynchronize 开始同步的方法
func StartSynchronize(value IValue) bool {
// 判断必要方法是否已经覆盖
if !reflect.ValueOf(value.TakeValue).CanInterface() {
panic(errors.New("TakeValue method is need OverWrite"))
}
// 防止忘记Close内存泄漏
runtime.SetFinalizer(value, func(obj IValue) {
obj.CloseSync()
})
if value.IsSync() {
return false
}
value.SetValue(value.TakeValue())
go func() {
for {
time.Sleep(value.UpdateInterval())
tvalue := value.TakeValue()
value.Lock()
defer value.Unlock()
isClose := value.IsCloseSync()
// 减少在休眠期间再操作一次, TakeValue
if isClose {
log.Println(value, "is Closed")
break
} else {
value.SetValue(tvalue)
}
}
}()
value.SetSync(true)
return true
}