package rpcclient import ( "fmt" "net" "strconv" "sync" "time" "lone-services/pkg/discovery" "lone-services/pkg/utils" "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/zrpc" ) type cacheEntry struct { cli zrpc.Client target string expireAt time.Time } const cacheTTL = 30 * time.Second var ( cacheLock sync.Mutex cache = make(map[string]*cacheEntry) ) func Get(serviceName string) (zrpc.Client, error) { if serviceName == utils.StringEmpty { err := fmt.Errorf("rpc serviceName is empty") logx.Error(err) return nil, err } cacheLock.Lock() entry, ok := cache[serviceName] if ok && time.Now().Before(entry.expireAt) { cacheLock.Unlock() return entry.cli, nil } delete(cache, serviceName) cacheLock.Unlock() inst, err := discovery.Pick(serviceName) if err != nil { err = fmt.Errorf("discovery pick %s failed: %w", serviceName, err) logx.Error(err) return nil, err } target := net.JoinHostPort(inst.IP, strconv.FormatUint(inst.Port, utils.NumberTen)) cli := zrpc.MustNewClient(zrpc.RpcClientConf{ Target: target, Timeout: utils.RpcTimeOut, }) cacheLock.Lock() cache[serviceName] = &cacheEntry{ cli: cli, target: target, expireAt: time.Now().Add(cacheTTL), } cacheLock.Unlock() return cli, nil }