commit 3ade58a75210515a8d88153ffa6663cef63e91b1 Author: eson <474420502@qq.com> Date: Thu Jan 24 03:18:17 2019 +0800 v1.0.0 diff --git a/base.go b/base.go new file mode 100644 index 0000000..435f1d1 --- /dev/null +++ b/base.go @@ -0,0 +1,18 @@ +package svalue + +import "log" + +func must(err error) { + if err != nil { + panic(err) + } +} + +func mustlog(err error) bool { + if err != nil { + log.Fatalln(err) + return false + } + + return true +} diff --git a/value.go b/value.go new file mode 100644 index 0000000..471cdc4 --- /dev/null +++ b/value.go @@ -0,0 +1,126 @@ +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{}) + + Close() + IsClose() bool + + SetSync(is bool) + IsSync() bool +} + +// Value 必须设置的动态类型 +type Value struct { + IValue + + value interface{} + mutex sync.Mutex + + isClose bool + isSync bool +} + +func (value *Value) SetValue(v interface{}) { + value.value = v +} + +func (value *Value) Lock() { + value.mutex.Lock() +} + +func (value *Value) Unlock() { + value.mutex.Unlock() +} + +func (value *Value) IsSync() bool { + return value.isSync +} + +func (value *Value) SetSync(is bool) { + value.isSync = is +} + +func (value *Value) Value() interface{} { + value.mutex.Lock() + defer value.mutex.Unlock() + return value.value +} + +func (value *Value) Close() { + value.mutex.Lock() + defer value.mutex.Unlock() + value.isClose = true +} + +func (value *Value) IsClose() bool { + return value.isClose +} + +func (value *Value) TakeUpdateInterval() time.Duration { + return time.Second * 5 +} + +func StartSynchronize(value IValue) bool { + if !reflect.ValueOf(value.TakeValue).CanInterface() { + panic(errors.New("TakeValue method is need OverWrite")) + } + + runtime.SetFinalizer(value, func(obj IValue) { + obj.Close() + }) + + if value.IsSync() { + return false + } + + go func() { + + for { + + value.Lock() + + value.SetValue(value.TakeValue()) + isClose := value.IsClose() + + value.Unlock() + + if isClose { + log.Println(value, "is Closed") + break + } + time.Sleep(value.UpdateInterval()) + if isClose { + log.Println(value, "is Closed") + break + } + + } + + }() + + value.SetSync(true) + return true +} diff --git a/value_test.go b/value_test.go new file mode 100644 index 0000000..2d8e774 --- /dev/null +++ b/value_test.go @@ -0,0 +1,26 @@ +package svalue + +import ( + "context" + "time" + + "go.etcd.io/etcd/clientv3" +) + +type EtcdCurl struct { + Value +} + +func (c *EtcdCurl) TakeValue() interface{} { + cli, err := clientv3.New(clientv3.Config{ + Endpoints: []string{"http://10.10.0.1:2279"}, + DialTimeout: 5 * time.Second, + }) + resp, err := cli.Get(context.Background(), "phone", clientv3.WithPrefix()) + must(err) + return string(resp.Kvs[0].Value)[0:20] +} + +func (c *EtcdCurl) UpdateInterval() time.Duration { + return time.Second * 1 +}