client.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  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. clients sync.Map
  12. once sync.Once
  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. value interface{}
  19. client *rpc.Client
  20. )
  21. value, ok = c.clients.Load(r.ServiceName)
  22. if ok {
  23. client = value.(*rpc.Client)
  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.DialerContext(ctx, "tcp", fmt.Sprintf("%s:%d", node.Address, node.Port)); err != nil {
  31. return
  32. }
  33. c.clients.Store(r.ServiceName, client)
  34. _EXEC:
  35. if resp, err = client.Do(ctx, rpc.NewRequest(r.Method, r.Body)); err != nil {
  36. c.clients.Delete(r.ServiceName)
  37. }
  38. return
  39. }
  40. func (c *Client) Close() (err error) {
  41. c.clients.Range(func(key, value interface{}) bool {
  42. client := value.(*rpc.Client)
  43. _ = client.Close()
  44. c.clients.Delete(key)
  45. return true
  46. })
  47. return
  48. }
  49. func NewClient(reg registry.Registry) *Client {
  50. return &Client{
  51. selector: registry.NewSelector(reg),
  52. }
  53. }