148 lines
2.7 KiB
Go
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
|
|
}
|