package generic import ( "context" "fmt" "google.golang.org/grpc" "sync" ) type GrpcGenericClientFactory struct { scheme string defaultOpts []grpc.DialOption clientCache *sync.Map } func NewGpcGenericClientFactory(scheme string, defaultOpts ...grpc.DialOption) *GrpcGenericClientFactory { return &GrpcGenericClientFactory{ scheme: scheme, defaultOpts: defaultOpts, } } func (f *GrpcGenericClientFactory) Init() { f.clientCache = &sync.Map{} } func (f *GrpcGenericClientFactory) NewClient(ctx context.Context, serviceName string, opts ...grpc.DialOption) (client *GrpcGenericClient, err error) { addr := fmt.Sprintf("%s:///%s", f.scheme, serviceName) dialOpts := make([]grpc.DialOption, 0, len(f.defaultOpts)+len(opts)) dialOpts = append(dialOpts, f.defaultOpts...) dialOpts = append(dialOpts, opts...) conn, err := grpc.DialContext(ctx, addr, dialOpts...) if err != nil { return } client = NewGpcGenericClient(serviceName, conn) err = client.Init(ctx) return } func (f *GrpcGenericClientFactory) GetClient(ctx context.Context, serviceName string, opts ...grpc.DialOption) (client *GrpcGenericClient, err error) { val, ok := f.clientCache.Load(serviceName) if ok { client = val.(*GrpcGenericClient) return } client, err = f.NewClient(ctx, serviceName, opts...) if err != nil { return } f.clientCache.Store(serviceName, client) return }