You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
61 lines
1.3 KiB
Go
61 lines
1.3 KiB
Go
4 years ago
|
package zrpc
|
||
4 years ago
|
|
||
|
import (
|
||
|
"context"
|
||
|
"sync"
|
||
|
|
||
4 years ago
|
"github.com/tal-tech/go-zero/core/syncx"
|
||
4 years ago
|
"github.com/tal-tech/go-zero/zrpc/internal"
|
||
|
"github.com/tal-tech/go-zero/zrpc/internal/auth"
|
||
4 years ago
|
"google.golang.org/grpc"
|
||
4 years ago
|
)
|
||
|
|
||
|
type RpcProxy struct {
|
||
|
backend string
|
||
4 years ago
|
clients map[string]Client
|
||
4 years ago
|
options []internal.ClientOption
|
||
4 years ago
|
sharedCalls syncx.SharedCalls
|
||
|
lock sync.Mutex
|
||
|
}
|
||
|
|
||
4 years ago
|
func NewProxy(backend string, opts ...internal.ClientOption) *RpcProxy {
|
||
4 years ago
|
return &RpcProxy{
|
||
|
backend: backend,
|
||
4 years ago
|
clients: make(map[string]Client),
|
||
4 years ago
|
options: opts,
|
||
|
sharedCalls: syncx.NewSharedCalls(),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (p *RpcProxy) TakeConn(ctx context.Context) (*grpc.ClientConn, error) {
|
||
|
cred := auth.ParseCredential(ctx)
|
||
|
key := cred.App + "/" + cred.Token
|
||
|
val, err := p.sharedCalls.Do(key, func() (interface{}, error) {
|
||
|
p.lock.Lock()
|
||
|
client, ok := p.clients[key]
|
||
|
p.lock.Unlock()
|
||
|
if ok {
|
||
|
return client, nil
|
||
|
}
|
||
|
|
||
4 years ago
|
opts := append(p.options, WithDialOption(grpc.WithPerRPCCredentials(&auth.Credential{
|
||
|
App: cred.App,
|
||
|
Token: cred.Token,
|
||
|
})))
|
||
|
client, err := NewClientWithTarget(p.backend, opts...)
|
||
4 years ago
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
p.lock.Lock()
|
||
|
p.clients[key] = client
|
||
|
p.lock.Unlock()
|
||
|
return client, nil
|
||
|
})
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
4 years ago
|
return val.(Client).Conn(), nil
|
||
4 years ago
|
}
|