Skip to content

Commit

Permalink
add comments
Browse files Browse the repository at this point in the history
  • Loading branch information
hui.wang committed Jan 6, 2022
1 parent 4baee75 commit 62c943e
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 18 deletions.
16 changes: 12 additions & 4 deletions kv/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,26 @@ import (
)

// todo Loder实现Reader接口完全对接到io.Reader,将远程的首次加载流程直接对接到xconf的WithReader
// Loader kv加载基础接口
type Loader interface {
// Name Loader名称
Name() string
// Get 主动获取指定confPath的数据
Get(ctx context.Context, confPath string) ([]byte, error)
// Watch Watch指定的confPath,数据发生变化会回调onContentChange
Watch(ctx context.Context, confPath string, onContentChange ContentChange)
Name() string
// Close 关闭
Close(ctx context.Context) error
}

// loaderImplement Loader特有逻辑对接,基础逻辑落实在Common对应接口中
type loaderImplement interface {
CloseImplement(ctx context.Context) error
GetImplement(ctx context.Context, confPath string) ([]byte, error)
WatchImplement(ctx context.Context, confPath string, onContentChange ContentChange)
}

// Common 基础的kv.Loader实现,实现基础逻辑,自定义的Loader对接到loaderImplement接口即可
type Common struct {
name string
Done chan struct{}
Expand Down Expand Up @@ -55,16 +62,17 @@ func (c *Common) CheckOnWatchError(watchError WatchError) {
}
}

func (c *Common) IsChanged(name string, data []byte) bool {
// IsChanged 指定的配置是否发生变化
func (c *Common) IsChanged(confPath string, data []byte) bool {
c.Lock()
defer c.Unlock()
hash := md5.New()
hash.Write(data)
md5Str := string(hash.Sum(nil))
if v, ok := c.fileMap[name]; ok && v == md5Str {
if v, ok := c.fileMap[confPath]; ok && v == md5Str {
return false
}
c.fileMap[name] = md5Str
c.fileMap[confPath] = md5Str
return true
}

Expand Down
7 changes: 5 additions & 2 deletions kv/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import (
"github.com/sandwich-go/xconf/secconf"
)

type ContentChange = func(string, string, []byte)
type WatchError = func(string, string, error)
// ContentChange kv数据发生变化时回调
type ContentChange = func(loaderName string, confPath string, content []byte)

// WatchError kv.Loader.Watch发生错误时回调
type WatchError = func(loaderName string, confPath string, watchErr error)

//go:generate optiongen --option_with_struct_name=false
func OptionsOptionDeclareWithDefault() interface{} {
Expand Down
11 changes: 5 additions & 6 deletions kv/xfile/xfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,11 @@ func (p *Loader) WatchImplement(ctx context.Context, confPath string, onContentC
}
select {
case event := <-p.watcher.Events:
if (event.Op&fsnotify.Write) == fsnotify.Write ||
(event.Op&fsnotify.Create) == fsnotify.Create {
name := strings.ReplaceAll(event.Name, "\\", "/")
if b, err := p.Get(ctx, name); err == nil {
if p.IsChanged(name, b) {
onContentChange(p.Name(), confPath, b)
if (event.Op&fsnotify.Write) == fsnotify.Write || (event.Op&fsnotify.Create) == fsnotify.Create {
confPathChanged := strings.ReplaceAll(event.Name, "\\", "/")
if b, err := p.Get(ctx, confPathChanged); err == nil {
if p.IsChanged(confPathChanged, b) {
onContentChange(p.Name(), confPathChanged, b)
}
}
}
Expand Down
18 changes: 12 additions & 6 deletions secconf/codec.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
package secconf

// Codec 编解码器接口
type Codec interface {
Apply(data []byte) ([]byte, error)
}

// CodecFunc
type CodecFunc func(data []byte) ([]byte, error)

// Apply CodecFunc 实现Codec接口
func (f CodecFunc) Apply(data []byte) ([]byte, error) { return f(data) }

// CodecFuncChain 编解码器链
type CodecFuncChain []CodecFunc

// Apply CodecFuncChain实现Codec接口
func (c CodecFuncChain) Apply(data []byte) (out []byte, err error) {
out = data
for _, v := range c {
Expand All @@ -17,13 +26,10 @@ func (c CodecFuncChain) Apply(data []byte) (out []byte, err error) {
return
}

// CodecFrom 由给定的CodecFunc列表构造Codec
func CodecFrom(codec ...CodecFunc) Codec { return CodecFuncChain(codec) }

type CodecFunc func(data []byte) ([]byte, error)

func (f CodecFunc) Apply(data []byte) ([]byte, error) { return f(data) }

// gzip => encrypt => base64
// StandardChainEncode 默认编码器链:gzip => encrypt => base64
func StandardChainEncode(encrypt CodecFunc) Codec {
return CodecFuncChain([]CodecFunc{
EncoderGZip,
Expand All @@ -32,7 +38,7 @@ func StandardChainEncode(encrypt CodecFunc) Codec {
})
}

// base64 => decrypt => gzip
// StandardChainDecode 默认解码器链:base64 => decrypt => gzip
func StandardChainDecode(decrypt CodecFunc) Codec {
return CodecFuncChain([]CodecFunc{
DecoderBase64,
Expand Down
5 changes: 5 additions & 0 deletions secconf/codec_decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"golang.org/x/crypto/openpgp"
)

// NewDecoderMagic 新建一个magic decoder,指定magic字段,解码的时候会检测该字段
func NewDecoderMagic(magic []byte) CodecFunc {
return func(data []byte) ([]byte, error) {
if len(magic) == 0 {
Expand All @@ -24,11 +25,13 @@ func NewDecoderMagic(magic []byte) CodecFunc {
}
}

// DecoderBase64 base64解码
func DecoderBase64(data []byte) ([]byte, error) {
decoder := base64.NewDecoder(base64.StdEncoding, bytes.NewBuffer(data))
return io.ReadAll(decoder)
}

// DecoderGZip gzip解码
func DecoderGZip(data []byte) ([]byte, error) {
gzReader, err := gzip.NewReader(bytes.NewBuffer(data))
if err != nil {
Expand All @@ -38,12 +41,14 @@ func DecoderGZip(data []byte) ([]byte, error) {
return ioutil.ReadAll(gzReader)
}

// NewDecoderXXTEA 新建xxtea解码器,指定key
func NewDecoderXXTEA(key []byte) CodecFunc {
return func(data []byte) ([]byte, error) {
return xxtea.Decrypt(data, key), nil
}
}

// NewDecoderOpenPGP 新建OpenPGP解码器,指定key
func NewDecoderOpenPGP(secertKeyring []byte) CodecFunc {
return func(data []byte) ([]byte, error) {
entityList, err := openpgp.ReadArmoredKeyRing(bytes.NewBuffer(secertKeyring))
Expand Down
6 changes: 6 additions & 0 deletions secconf/codec_encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"golang.org/x/crypto/openpgp"
)

// EncoderBase64 base64编码器
func EncoderBase64(data []byte) ([]byte, error) {
buffer := new(bytes.Buffer)
encoder := base64.NewEncoder(base64.StdEncoding, buffer)
Expand All @@ -23,6 +24,7 @@ func EncoderBase64(data []byte) ([]byte, error) {
return buffer.Bytes(), nil
}

// EncoderGZip gzip编码器
func EncoderGZip(data []byte) ([]byte, error) {
var buf bytes.Buffer
writer := gzip.NewWriter(&buf)
Expand All @@ -31,6 +33,7 @@ func EncoderGZip(data []byte) ([]byte, error) {
return buf.Bytes(), err
}

// NewEncoderMagic magic编码器,指定magic,编码时会自动将magic添加到字段头
func NewEncoderMagic(magic []byte) CodecFunc {
return func(data []byte) ([]byte, error) {
if len(magic) == 0 {
Expand All @@ -42,12 +45,15 @@ func NewEncoderMagic(magic []byte) CodecFunc {
return append(magic[:], data[:]...), nil
}
}

// NewEncoderXXTEA xxtea编码器,指定key
func NewEncoderXXTEA(key []byte) CodecFunc {
return func(data []byte) ([]byte, error) {
return xxtea.Encrypt(data, key), nil
}
}

// NewEncoderOpenPGP OpenPGP编码器,指定key
func NewEncoderOpenPGP(secertKeyring []byte) CodecFunc {
return func(data []byte) ([]byte, error) {
entityList, err := openpgp.ReadArmoredKeyRing(bytes.NewBuffer(secertKeyring))
Expand Down
2 changes: 2 additions & 0 deletions secconf/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type secReader struct {
cf Codec
}

// Read secReader实现io.Reader接口
func (s *secReader) Read(p []byte) (n int, err error) {
if s.cached == nil {
all, err := io.ReadAll(s.wrapped)
Expand All @@ -28,4 +29,5 @@ func (s *secReader) Read(p []byte) (n int, err error) {
return s.cached.Read(p)
}

// Reader 用给定的Codec将给定的reader封装成新的io.Reader,数据读取流程中会经给定的Codec进行编解码
func Reader(reader io.Reader, cf Codec) io.Reader { return &secReader{wrapped: reader, cf: cf} }
5 changes: 5 additions & 0 deletions xconf.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,15 @@ type XConf struct {
atomicSetFunc AtomicSetFunc
}

// New 构造新的Xconf
func New(opts ...Option) *XConf { return NewWithConf(NewOptions(opts...)) }

// NewWithoutFlagEnv 构造新的Xconf,移除FlagSet和Environ解析
func NewWithoutFlagEnv(opts ...Option) *XConf {
return New(append(opts, WithFlagSet(nil), WithEnviron())...)
}

// NewWithConf 由指定的配置构造XConf
func NewWithConf(cc *Options) *XConf {
x := &XConf{cc: cc}
x.updated = make(chan interface{}, 1)
Expand All @@ -52,6 +56,7 @@ func NewWithConf(cc *Options) *XConf {
return x
}

// AtomicSetFunc
type AtomicSetFunc = func(interface{})

func (x *XConf) Latest() (interface{}, error) {
Expand Down
5 changes: 5 additions & 0 deletions xfield/tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ package xfield

import "strings"

// TagNotLeaf xconf中指定TagNotLeaf标志字段非叶子节点,用于map
const TagNotLeaf = "notleaf"

// TagList tag列表,全量
type TagList []string

// Has 是否含有指定的标签,区分大小写
func (t TagList) Has(opt string) bool {
for _, tagOpt := range t {
if tagOpt == opt {
Expand All @@ -15,6 +18,7 @@ func (t TagList) Has(opt string) bool {
return false
}

// HasIgnoreCase 是否含有指定的标签,不区分大小写
func (t TagList) HasIgnoreCase(opt string) bool {
for _, tagOpt := range t {
if strings.EqualFold(tagOpt, opt) {
Expand All @@ -24,6 +28,7 @@ func (t TagList) HasIgnoreCase(opt string) bool {
return false
}

// ParseTag 解析指定的tag
// tag is one of followings:
// ""
// "name"
Expand Down

0 comments on commit 62c943e

Please sign in to comment.