client.go 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. package micro
  2. import (
  3. "context"
  4. "fmt"
  5. "git.nspix.com/golang/micro/gateway/rpc"
  6. "git.nspix.com/golang/micro/registry"
  7. "sync"
  8. )
  9. type Client struct {
  10. selector *registry.Selector
  11. clientLocker sync.RWMutex
  12. clients map[string]*rpc.Client
  13. }
  14. func (c *Client) Do(ctx context.Context, r *Request) (resp Response, err error) {
  15. var (
  16. ok bool
  17. node *registry.ServiceNode
  18. client *rpc.Client
  19. )
  20. c.clientLocker.RLock()
  21. client, ok = c.clients[r.ServiceName]
  22. c.clientLocker.RUnlock()
  23. if ok {
  24. goto _EXEC
  25. }
  26. if node, err = c.selector.Select(ctx, r.ServiceName); err != nil {
  27. return
  28. }
  29. client = rpc.NewClient()
  30. if err = client.Dialer("tcp", fmt.Sprintf("%s:%d", node.Address, node.Port)); err != nil {
  31. return
  32. }
  33. _EXEC:
  34. return client.Do(ctx, rpc.NewRequest(r.Method, r.Body))
  35. }
  36. func (c *Client) Close() (err error) {
  37. c.clientLocker.Lock()
  38. defer c.clientLocker.Unlock()
  39. for name, client := range c.clients {
  40. _ = client.Close()
  41. delete(c.clients, name)
  42. }
  43. return
  44. }
  45. func NewClient(reg registry.Registry) *Client {
  46. return &Client{
  47. clients: make(map[string]*rpc.Client),
  48. selector: registry.NewSelector(reg),
  49. }
  50. }