package srvdata import ( "crypto/md5" "encoding/hex" "errors" "os" "strings" ) var fileSignMap = make(map[string]string) type DataLoader interface { Load(fileFullPath string) error Reload(fileFullPath string) error } type DataHolder interface { unmarshal([]byte) error reunmarshal([]byte) error } type JsonDataLoader struct { dh DataHolder } func (this *JsonDataLoader) Load(fileFullPath string) error { buf, err := os.ReadFile(fileFullPath) if err != nil { return err } h := md5.New() _, err = h.Write(buf) if err != nil { return err } fileSign := hex.EncodeToString(h.Sum(nil)) fileSignMap[fileFullPath] = fileSign if this.dh != nil { err = this.dh.unmarshal(buf) } return err } func (this *JsonDataLoader) Reload(fileFullPath string) error { buf, err := os.ReadFile(fileFullPath) if err != nil { return err } h := md5.New() _, err = h.Write(buf) if err != nil { return err } fileSign := hex.EncodeToString(h.Sum(nil)) if preSign, exist := fileSignMap[fileFullPath]; exist { if preSign == fileSign { return nil } } fileSignMap[fileFullPath] = fileSign if this.dh != nil { err = this.dh.reunmarshal(buf) } return err } type ProtobufDataLoader struct { dh DataHolder } func (this *ProtobufDataLoader) Load(fileFullPath string) error { buf, err := os.ReadFile(fileFullPath) if err != nil { return err } h := md5.New() _, err = h.Write(buf) if err != nil { return err } fileSign := hex.EncodeToString(h.Sum(nil)) fileSignMap[fileFullPath] = fileSign if this.dh != nil { err = this.dh.unmarshal(buf) } return err } func (this *ProtobufDataLoader) Reload(fileFullPath string) error { buf, err := os.ReadFile(fileFullPath) if err != nil { return err } h := md5.New() _, err = h.Write(buf) if err != nil { return err } fileSign := hex.EncodeToString(h.Sum(nil)) if preSign, exist := fileSignMap[fileFullPath]; exist { if preSign == fileSign { return errors.New("content no modify") } } fileSignMap[fileFullPath] = fileSign if this.dh != nil { err = this.dh.reunmarshal(buf) } return err } var DataMgr = &dataMgr{ loaders: make(map[string]DataLoader), afterLoaders: make(map[string][]DataLoader), } type dataMgr struct { loaders map[string]DataLoader afterLoaders map[string][]DataLoader } // register 注册数据加载器,这个应该只是自动生产的代码中会用到,其它地方用不到 func (this *dataMgr) register(name string, loader DataLoader) { this.loaders[strings.ToLower(name)] = loader } // RegisterLoader 注册数据加载器,如果需要依赖配置表再生成新结构的数据用这个 // loader的方法调用会在配置表加载之后调用 func (this *dataMgr) RegisterLoader(name string, loader DataLoader) { this.afterLoaders[strings.ToLower(name)] = append(this.afterLoaders[strings.ToLower(name)], loader) } func (this *dataMgr) GetLoader(name string) []DataLoader { var ret []DataLoader if loader, exist := this.loaders[strings.ToLower(name)]; exist { ret = append(ret, loader) } if loader, exist := this.afterLoaders[strings.ToLower(name)]; exist { ret = append(ret, loader...) } return ret }