From 981e1e0cf0f99904d62be47bdf9c9e28f2d13b98 Mon Sep 17 00:00:00 2001 From: "dc.To" Date: Thu, 7 Aug 2025 09:52:32 +0800 Subject: [PATCH] update invoke add atomic with context config --- apapter/atomic.go | 70 ++++++++++++++++++++++++++++++++++++++++++++ apapter/context.go | 50 +++++++++++++++++++++++++++++++ chain/clientchain.go | 15 ++-------- config/config.go | 29 ------------------ 4 files changed, 123 insertions(+), 41 deletions(-) create mode 100644 apapter/atomic.go create mode 100644 apapter/context.go delete mode 100644 config/config.go diff --git a/apapter/atomic.go b/apapter/atomic.go new file mode 100644 index 0000000..cc692c3 --- /dev/null +++ b/apapter/atomic.go @@ -0,0 +1,70 @@ +package apapter + +import ( + "context" + "errors" + "sync/atomic" + + "github.com/gogf/gf/v2/container/gvar" + "github.com/gogf/gf/v2/encoding/gbase64" + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/frame/g" + "google.golang.org/grpc/metadata" +) + +/** + * 原子钟接口配置 + * @author dc.To + * @version 20250807 + */ +type AtomicAdapter struct { + store atomic.Value + adapter string +} + +func NewAtomicAdapter(ctx context.Context, adapter string) *AtomicAdapter { + a := &AtomicAdapter{adapter: adapter} + md, ok := metadata.FromIncomingContext(ctx) + if ok { + if c := md.Get(a.adapter); len(c) > 0 { + a.SetContent(gjson.New(gbase64.MustDecodeToString(c[0])).Map()) + } else { + g.Log("cfg").Error(ctx, "No Metadata from incoming cfg context") + } + } + return a +} + +func (a *AtomicAdapter) SetContent(content map[string]interface{}) error { + a.store.Store(content) + return nil +} + +func (a *AtomicAdapter) Available(ctx context.Context, resource ...string) (ok bool) { + return a.store.Load() != nil +} + +func (a *AtomicAdapter) Get(ctx context.Context, pattern string) (value interface{}, err error) { + raw := a.store.Load() + if raw == nil { + return nil, errors.New("config not loaded") + } + data := raw.(map[string]interface{}) + if v, ok := data[pattern]; ok { + return gvar.New(v), nil + } + return gvar.New(nil), nil +} + +func (a *AtomicAdapter) Data(ctx context.Context) (data map[string]interface{}, err error) { + raw := a.store.Load() + if raw == nil { + return nil, errors.New("config not loaded") + } + original := raw.(map[string]interface{}) + clone := make(map[string]interface{}, len(original)) + for k, v := range original { + clone[k] = v + } + return clone, nil +} diff --git a/apapter/context.go b/apapter/context.go new file mode 100644 index 0000000..fce990d --- /dev/null +++ b/apapter/context.go @@ -0,0 +1,50 @@ +package apapter + +import ( + "context" + + "github.com/gogf/gf/v2/container/gvar" + "github.com/gogf/gf/v2/encoding/gbase64" + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/frame/g" + "google.golang.org/grpc/metadata" +) + +/** + * @Description: ContextAdapter + * @author dc.To + * @version 20250807 + */ +type ContextAdapter struct { + ctx context.Context + adapter string +} + +func NewContextAdapter(ctx context.Context, adapter string) *ContextAdapter { + return &ContextAdapter{ctx: ctx, adapter: adapter} +} + +func (a *ContextAdapter) ctxWithConfig(ctx context.Context) *gvar.Var { + md, ok := metadata.FromIncomingContext(ctx) + if ok { + if c := md.Get(a.adapter); len(c) > 0 { + return gvar.New(gbase64.MustDecodeToString(c[0])) + } + } + g.Log("cfg").Error(ctx, "No Metadata from ["+a.adapter+"] cfg context") + + return gvar.New(nil) +} + +func (a *ContextAdapter) Available(ctx context.Context, resource ...string) (ok bool) { + return a.ctxWithConfig(ctx) != nil +} + +func (a *ContextAdapter) Get(ctx context.Context, pattern string) (value interface{}, err error) { + + return gjson.New(a.ctxWithConfig(ctx)).Get(pattern).Val(), nil +} + +func (a *ContextAdapter) Data(ctx context.Context) (data map[string]interface{}, err error) { + return gjson.New(a.ctxWithConfig(ctx)).Map(), nil +} diff --git a/chain/clientchain.go b/chain/clientchain.go index ce65f4d..6c0a491 100644 --- a/chain/clientchain.go +++ b/chain/clientchain.go @@ -4,9 +4,8 @@ import ( "context" "strings" - "github.com/gogf/gf/v2/encoding/gbase64" + "git.linkiio.cn/linkpay/api/invoke/apapter" "github.com/gogf/gf/v2/frame/g" - "github.com/gogf/gf/v2/os/gcfg" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) @@ -46,20 +45,12 @@ func ClientContextUnaryChain(ctx context.Context, req interface{}, info *grpc.Un * @version 20250418 */ func ClientMetadataUnaryChain(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + md, ok := metadata.FromIncomingContext(ctx) if ok { for k, v := range md { if strings.HasPrefix(k, "x-cfg-") && len(v) > 0 { - c := strings.Join(v, "") - if len(c) > 0 { - a, err := gcfg.NewAdapterContent(gbase64.MustDecodeToString(v[0])) - if err != nil { - g.Log("unary").Error(ctx, err) - continue - } - g.Cfg(strings.TrimPrefix(k, "x-cfg-")).SetAdapter(a) - } - + g.Cfg(strings.TrimPrefix(k, "x-cfg-")).SetAdapter(apapter.NewContextAdapter(ctx, k)) } } } else { diff --git a/config/config.go b/config/config.go deleted file mode 100644 index 72b65db..0000000 --- a/config/config.go +++ /dev/null @@ -1,29 +0,0 @@ -package config - -import ( - "context" - - "github.com/gogf/gf/v2/encoding/gbase64" - "github.com/gogf/gf/v2/frame/g" - "github.com/gogf/gf/v2/os/gcfg" - "google.golang.org/grpc/metadata" -) - -func All(ctx context.Context) *gcfg.Config { - return g.Cfg() -} - -func Api(ctx context.Context) *gcfg.Config { - md, ok := metadata.FromIncomingContext(ctx) - c := md.Get("x-cfg-api") - if ok && len(c) > 0 { - b, _ := gbase64.DecodeToString(c[0]) - a, err := gcfg.NewAdapterContent(b) - if err != nil { - g.Log("config with api").Error(ctx, err) - } - return gcfg.NewWithAdapter(a) - } - - return g.Cfg("api") -}