上传配置中心自动检测机制
This commit is contained in:
parent
eb638559cf
commit
203b0f97b7
@ -20,6 +20,7 @@ func (this *ServiceBase) InitSys() {
|
|||||||
if err := configure.OnInit(this.GetSettings().Sys["configure"]); err != nil {
|
if err := configure.OnInit(this.GetSettings().Sys["configure"]); err != nil {
|
||||||
panic(fmt.Sprintf("init sys.configure err: %s", err.Error()))
|
panic(fmt.Sprintf("init sys.configure err: %s", err.Error()))
|
||||||
} else {
|
} else {
|
||||||
|
configure.Start()
|
||||||
log.Infof("init sys.configure success!")
|
log.Infof("init sys.configure success!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,14 @@ package configure
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"go_dreamfactory/lego/sys/log"
|
||||||
|
"io/fs"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
jsoniter "github.com/json-iterator/go"
|
||||||
)
|
)
|
||||||
@ -22,8 +25,10 @@ type configurehandle struct {
|
|||||||
func newSys(options Options) (sys *Configure, err error) {
|
func newSys(options Options) (sys *Configure, err error) {
|
||||||
sys = &Configure{
|
sys = &Configure{
|
||||||
options: options,
|
options: options,
|
||||||
configurehandles: map[string]*configurehandle{},
|
closeSignal: make(chan struct{}),
|
||||||
configure: map[string]interface{}{},
|
configurehandles: make(map[string]*configurehandle),
|
||||||
|
configure: make(map[string]interface{}),
|
||||||
|
fileinfos: make(map[string]*FileInfo),
|
||||||
}
|
}
|
||||||
err = sys.init()
|
err = sys.init()
|
||||||
return
|
return
|
||||||
@ -31,10 +36,12 @@ func newSys(options Options) (sys *Configure, err error) {
|
|||||||
|
|
||||||
type Configure struct {
|
type Configure struct {
|
||||||
options Options
|
options Options
|
||||||
|
closeSignal chan struct{}
|
||||||
hlock sync.RWMutex
|
hlock sync.RWMutex
|
||||||
configurehandles map[string]*configurehandle
|
configurehandles map[string]*configurehandle
|
||||||
clock sync.RWMutex
|
clock sync.RWMutex
|
||||||
configure map[string]interface{}
|
configure map[string]interface{}
|
||||||
|
fileinfos map[string]*FileInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Configure) init() (err error) {
|
func (this *Configure) init() (err error) {
|
||||||
@ -42,6 +49,26 @@ func (this *Configure) init() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *Configure) Start() (err error) {
|
||||||
|
tc := time.NewTicker(time.Second * time.Duration(this.options.CheckInterval))
|
||||||
|
go func() {
|
||||||
|
locp:
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-this.closeSignal:
|
||||||
|
break locp
|
||||||
|
case <-tc.C:
|
||||||
|
this.checkConfigure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (this *Configure) Stop() (err error) {
|
||||||
|
this.closeSignal <- struct{}{}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
//加载配置文件
|
//加载配置文件
|
||||||
func (this *Configure) RegisterConfigure(name string, fn interface{}) (err error) {
|
func (this *Configure) RegisterConfigure(name string, fn interface{}) (err error) {
|
||||||
this.hlock.RLock()
|
this.hlock.RLock()
|
||||||
@ -94,8 +121,7 @@ func (this *Configure) UpdateConfigure(names ...string) (err error) {
|
|||||||
handle, ok := this.configurehandles[v]
|
handle, ok := this.configurehandles[v]
|
||||||
this.hlock.RUnlock()
|
this.hlock.RUnlock()
|
||||||
if !ok {
|
if !ok {
|
||||||
err = fmt.Errorf("no RegisterConfigure:%s", v)
|
continue
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if err = this.loaderConfigure(v, handle); err != nil {
|
if err = this.loaderConfigure(v, handle); err != nil {
|
||||||
err = fmt.Errorf("loaderConfigure:%s err:%v", v, err)
|
err = fmt.Errorf("loaderConfigure:%s err:%v", v, err)
|
||||||
@ -120,12 +146,19 @@ func (this *Configure) GetConfigure(name string) (v interface{}, err error) {
|
|||||||
func (this *Configure) loaderConfigure(name string, handle *configurehandle) (err error) {
|
func (this *Configure) loaderConfigure(name string, handle *configurehandle) (err error) {
|
||||||
var (
|
var (
|
||||||
fliepath string
|
fliepath string
|
||||||
|
fileInfo fs.FileInfo
|
||||||
file *os.File
|
file *os.File
|
||||||
bytes []byte
|
bytes []byte
|
||||||
data []map[string]interface{}
|
data []map[string]interface{}
|
||||||
returnValues []reflect.Value
|
returnValues []reflect.Value
|
||||||
)
|
)
|
||||||
|
|
||||||
fliepath = path.Join(this.options.ConfigurePath, name)
|
fliepath = path.Join(this.options.ConfigurePath, name)
|
||||||
|
if fileInfo, err = os.Stat(fliepath); err != nil {
|
||||||
|
err = fmt.Errorf("no fond file:%s", fliepath)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if file, err = os.Open(fliepath); err != nil {
|
if file, err = os.Open(fliepath); err != nil {
|
||||||
err = fmt.Errorf("no fond file:%s", fliepath)
|
err = fmt.Errorf("no fond file:%s", fliepath)
|
||||||
return
|
return
|
||||||
@ -147,6 +180,30 @@ func (this *Configure) loaderConfigure(name string, handle *configurehandle) (er
|
|||||||
}
|
}
|
||||||
this.clock.Lock()
|
this.clock.Lock()
|
||||||
this.configure[name] = returnValues[0].Interface()
|
this.configure[name] = returnValues[0].Interface()
|
||||||
|
this.fileinfos[fileInfo.Name()] = &FileInfo{Name: name, Size: fileInfo.Size(), ModTime: fileInfo.ModTime()}
|
||||||
this.clock.Unlock()
|
this.clock.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//检查配置文件是否有更新
|
||||||
|
func (this *Configure) checkConfigure() {
|
||||||
|
if dir, err := ioutil.ReadDir(this.options.ConfigurePath); err != nil {
|
||||||
|
log.Errorf("[Configure Sys] checkConfigure err:%v", err)
|
||||||
|
} else {
|
||||||
|
for _, fi := range dir {
|
||||||
|
if !fi.IsDir() { //不处理目录代码
|
||||||
|
this.clock.RLock()
|
||||||
|
v, ok := this.fileinfos[fi.Name()]
|
||||||
|
this.clock.RUnlock()
|
||||||
|
if ok && fi.ModTime().After(v.ModTime) {
|
||||||
|
this.hlock.RLock()
|
||||||
|
handle := this.configurehandles[v.Name]
|
||||||
|
this.hlock.RUnlock()
|
||||||
|
if err = this.loaderConfigure(v.Name, handle); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,12 +1,22 @@
|
|||||||
package configure
|
package configure
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
系统 服务配置中心
|
系统 服务配置中心
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
//配置文件信息
|
||||||
|
FileInfo struct {
|
||||||
|
Name string // 文件名
|
||||||
|
Size int64 // 文件大小
|
||||||
|
ModTime time.Time // 文件修改时间
|
||||||
|
}
|
||||||
ISys interface {
|
ISys interface {
|
||||||
|
Start() (err error)
|
||||||
|
Stop() (err error)
|
||||||
RegisterConfigure(name string, fn interface{}) (err error) //注册配置
|
RegisterConfigure(name string, fn interface{}) (err error) //注册配置
|
||||||
UpdateConfigure(names ...string) (err error) //更新配置
|
UpdateConfigure(names ...string) (err error) //更新配置
|
||||||
GetConfigure(name string) (v interface{}, err error) //获取配置
|
GetConfigure(name string) (v interface{}, err error) //获取配置
|
||||||
@ -32,7 +42,12 @@ func NewSys(option ...Option) (sys ISys, err error) {
|
|||||||
defsys, err = newSys(options)
|
defsys, err = newSys(options)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
func Start() (err error) {
|
||||||
|
return defsys.Start()
|
||||||
|
}
|
||||||
|
func Stop() (err error) {
|
||||||
|
return defsys.Stop()
|
||||||
|
}
|
||||||
func RegisterConfigure(name string, fn interface{}) (err error) {
|
func RegisterConfigure(name string, fn interface{}) (err error) {
|
||||||
return defsys.RegisterConfigure(name, fn)
|
return defsys.RegisterConfigure(name, fn)
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,14 @@ import (
|
|||||||
|
|
||||||
type Option func(*Options)
|
type Option func(*Options)
|
||||||
type Options struct {
|
type Options struct {
|
||||||
ConfigurePath string
|
ConfigurePath string //配置中心路径
|
||||||
|
CheckInterval int //配置文件更新检查间隔时间 单位秒
|
||||||
}
|
}
|
||||||
|
|
||||||
func newOptions(config map[string]interface{}, opts ...Option) (Options, error) {
|
func newOptions(config map[string]interface{}, opts ...Option) (Options, error) {
|
||||||
options := Options{}
|
options := Options{
|
||||||
|
CheckInterval: 60,
|
||||||
|
}
|
||||||
if config != nil {
|
if config != nil {
|
||||||
mapstructure.Decode(config, &options)
|
mapstructure.Decode(config, &options)
|
||||||
}
|
}
|
||||||
@ -21,7 +24,9 @@ func newOptions(config map[string]interface{}, opts ...Option) (Options, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newOptionsByOption(opts ...Option) (Options, error) {
|
func newOptionsByOption(opts ...Option) (Options, error) {
|
||||||
options := Options{}
|
options := Options{
|
||||||
|
CheckInterval: 60,
|
||||||
|
}
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&options)
|
o(&options)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user