92 lines
1.8 KiB
Go
92 lines
1.8 KiB
Go
|
package invoke
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"google.golang.org/grpc"
|
||
|
"google.golang.org/grpc/credentials/insecure"
|
||
|
"google.golang.org/grpc/resolver"
|
||
|
"sync"
|
||
|
"time"
|
||
|
"ultone/internal/tool"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
SCHEME = "sonar"
|
||
|
)
|
||
|
|
||
|
type Client[T any] struct {
|
||
|
domain string
|
||
|
endpoints []string
|
||
|
fn func(grpc.ClientConnInterface) T
|
||
|
opts []grpc.DialOption
|
||
|
|
||
|
cc *grpc.ClientConn
|
||
|
}
|
||
|
|
||
|
func (c *Client[T]) Session() T {
|
||
|
return c.fn(c.cc)
|
||
|
}
|
||
|
|
||
|
var (
|
||
|
clients = &sync.Map{}
|
||
|
)
|
||
|
|
||
|
// NewClient
|
||
|
/*
|
||
|
* domain => Example: sonar_search
|
||
|
* endpoints => Example: []string{"sonar_search:8080", "sonar_search:80801"} or []string{"10.10.10.10:32000", "10.10.10.10:32001"}
|
||
|
* fn => Example: system.NewSystemSrvClient
|
||
|
* opts => Example: grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||
|
*/
|
||
|
func NewClient[T any](
|
||
|
domain string,
|
||
|
endpoints []string,
|
||
|
fn func(grpc.ClientConnInterface) T,
|
||
|
opts ...grpc.DialOption,
|
||
|
) (*Client[T], error) {
|
||
|
|
||
|
cached, ok := clients.Load(domain)
|
||
|
if ok {
|
||
|
if client, ok := cached.(*Client[T]); ok {
|
||
|
return client, nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
resolved := resolver.State{Addresses: make([]resolver.Address, 0)}
|
||
|
|
||
|
locker.Lock()
|
||
|
for _, item := range endpoints {
|
||
|
resolved.Addresses = append(resolved.Addresses, resolver.Address{Addr: item})
|
||
|
}
|
||
|
ips[domain] = resolved
|
||
|
locker.Unlock()
|
||
|
|
||
|
fullAddress := fmt.Sprintf("%s://%s", SCHEME, domain)
|
||
|
|
||
|
opts = append(opts,
|
||
|
grpc.WithResolvers(myBuilder),
|
||
|
grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy":"round_robin"}`),
|
||
|
grpc.WithChainUnaryInterceptor(retryInterceptor(3, 3*time.Second)),
|
||
|
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||
|
)
|
||
|
|
||
|
conn, err := grpc.DialContext(
|
||
|
tool.Timeout(3),
|
||
|
fullAddress,
|
||
|
opts...,
|
||
|
)
|
||
|
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
c := &Client[T]{
|
||
|
cc: conn,
|
||
|
fn: fn,
|
||
|
}
|
||
|
|
||
|
clients.Store(domain, c)
|
||
|
|
||
|
return c, nil
|
||
|
}
|