client.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package http
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "net/http"
  6. "github.com/go-kit/kit/endpoint"
  7. httptransport "github.com/go-kit/kit/transport/http"
  8. "golang.org/x/net/context"
  9. "github.com/cryptix/exp/todoKitSvc/reqrep"
  10. "github.com/cryptix/exp/todoKitSvc/todosvc"
  11. )
  12. func NewClient(method, host string, before ...httptransport.BeforeFunc) todosvc.Endpoints {
  13. return todosvc.Endpoints{
  14. Add: makeAddClientEndpoint(method, host+"/add", before...),
  15. List: makeListClientEndpoint(method, host+"/list", before...),
  16. }
  17. }
  18. func makeAddClientEndpoint(method, url string, before ...httptransport.BeforeFunc) endpoint.Endpoint {
  19. return func(ctx0 context.Context, request interface{}) (interface{}, error) {
  20. var (
  21. ctx, cancel = context.WithCancel(ctx0)
  22. errs = make(chan error, 1)
  23. responses = make(chan interface{}, 1)
  24. )
  25. defer cancel()
  26. go func() {
  27. var buf bytes.Buffer
  28. if err := json.NewEncoder(&buf).Encode(request); err != nil {
  29. errs <- err
  30. return
  31. }
  32. req, err := http.NewRequest(method, url, &buf)
  33. if err != nil {
  34. errs <- err
  35. return
  36. }
  37. for _, f := range before {
  38. ctx = f(ctx, req)
  39. }
  40. resp, err := http.DefaultClient.Do(req)
  41. if err != nil {
  42. errs <- err
  43. return
  44. }
  45. defer resp.Body.Close()
  46. var response reqrep.AddResponse
  47. if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
  48. errs <- err
  49. return
  50. }
  51. responses <- response
  52. }()
  53. select {
  54. case <-ctx.Done():
  55. return nil, context.DeadlineExceeded
  56. case err := <-errs:
  57. return nil, err
  58. case response := <-responses:
  59. return response, nil
  60. }
  61. }
  62. }
  63. func makeListClientEndpoint(method, url string, before ...httptransport.BeforeFunc) endpoint.Endpoint {
  64. return func(ctx0 context.Context, request interface{}) (interface{}, error) {
  65. var (
  66. ctx, cancel = context.WithCancel(ctx0)
  67. errs = make(chan error, 1)
  68. responses = make(chan interface{}, 1)
  69. )
  70. defer cancel()
  71. go func() {
  72. var buf bytes.Buffer
  73. if err := json.NewEncoder(&buf).Encode(request); err != nil {
  74. errs <- err
  75. return
  76. }
  77. req, err := http.NewRequest(method, url, &buf)
  78. if err != nil {
  79. errs <- err
  80. return
  81. }
  82. for _, f := range before {
  83. ctx = f(ctx, req)
  84. }
  85. resp, err := http.DefaultClient.Do(req)
  86. if err != nil {
  87. errs <- err
  88. return
  89. }
  90. defer resp.Body.Close()
  91. var response reqrep.ListResponse
  92. if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
  93. errs <- err
  94. return
  95. }
  96. responses <- response
  97. }()
  98. select {
  99. case <-ctx.Done():
  100. return nil, context.DeadlineExceeded
  101. case err := <-errs:
  102. return nil, err
  103. case response := <-responses:
  104. return response, nil
  105. }
  106. }
  107. }