You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

channel.go 4.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. package rpc
  2. import (
  3. "gitlink.org.cn/cloudream/common/utils/serder"
  4. "gitlink.org.cn/cloudream/jcs-pub/common/ecode"
  5. )
  6. var ErrChannelClosed = Failed(ecode.ChannelClosed, "channel closed")
  7. type ChanSender[T any] interface {
  8. Send(val T) *CodeError
  9. Close()
  10. // 关闭连接,并发送错误码。注意:客户端部分的Channel调用此函数时设置的err不会被送到服务端,因为GRPC没有提供这样的机制。
  11. CloseWithError(err *CodeError)
  12. }
  13. type ChanReceiver[T any] interface {
  14. Receive() (T, *CodeError)
  15. Close()
  16. // 关闭连接,并发送错误码。注意:客户端部分的Channel调用此函数时设置的err不会被送到服务端,因为GRPC没有提供这样的机制。
  17. CloseWithError(err *CodeError)
  18. }
  19. type BidChan[Recv, Send any] interface {
  20. ChanSender[Send]
  21. ChanReceiver[Recv]
  22. }
  23. type fusedChannel[Recv, Send any] struct {
  24. err *CodeError
  25. }
  26. func (f *fusedChannel[Recv, Send]) Receive() (Recv, *CodeError) {
  27. var val Recv
  28. return val, f.err
  29. }
  30. func (f *fusedChannel[Recv, Send]) Send(val Send) *CodeError {
  31. return f.err
  32. }
  33. func (f *fusedChannel[Recv, Send]) Close() {
  34. }
  35. func (f *fusedChannel[Recv, Send]) CloseWithError(err *CodeError) {
  36. }
  37. func NewFusedChan[Recv, Send any](err *CodeError) BidChan[Recv, Send] {
  38. return &fusedChannel[Recv, Send]{err: err}
  39. }
  40. type bidChanClient[Recv, Send any] struct {
  41. cli BidChannelAPIClient
  42. cancelFn func()
  43. lastErr *CodeError
  44. }
  45. func NewBidChanClient[Recv, Send any](cli BidChannelAPIClient, cancelFn func()) BidChan[Recv, Send] {
  46. return &bidChanClient[Recv, Send]{cli: cli, cancelFn: cancelFn}
  47. }
  48. func (c *bidChanClient[Recv, Send]) Send(val Send) *CodeError {
  49. if c.lastErr != nil {
  50. return c.lastErr
  51. }
  52. data, err := serder.ObjectToJSONEx(val)
  53. if err != nil {
  54. c.cancelFn()
  55. c.lastErr = Failed(ecode.OperationFailed, err.Error())
  56. return Failed(ecode.OperationFailed, err.Error())
  57. }
  58. err = c.cli.Send(&Request{Payload: data})
  59. if err != nil {
  60. c.cancelFn()
  61. c.lastErr = getCodeError(err)
  62. return c.lastErr
  63. }
  64. return nil
  65. }
  66. func (c *bidChanClient[Recv, Send]) Receive() (Recv, *CodeError) {
  67. if c.lastErr != nil {
  68. var def Recv
  69. return def, c.lastErr
  70. }
  71. resp, err := c.cli.Recv()
  72. if err != nil {
  73. c.cancelFn()
  74. c.lastErr = getCodeError(err)
  75. var def Recv
  76. return def, c.lastErr
  77. }
  78. resp2, err := serder.JSONToObjectEx[Recv](resp.Payload)
  79. if err != nil {
  80. c.cancelFn()
  81. c.lastErr = Failed(ecode.OperationFailed, err.Error())
  82. var def Recv
  83. return def, c.lastErr
  84. }
  85. return resp2, nil
  86. }
  87. func (c *bidChanClient[Recv, Send]) Close() {
  88. if c.lastErr != nil {
  89. return
  90. }
  91. c.cli.CloseSend()
  92. c.lastErr = ErrChannelClosed
  93. }
  94. func (c *bidChanClient[Recv, Send]) CloseWithError(err *CodeError) {
  95. if c.lastErr != nil {
  96. return
  97. }
  98. c.cancelFn()
  99. c.lastErr = err
  100. }
  101. type bidChanServer[Recv, Send any] struct {
  102. svr BidChannelAPIServer
  103. errChan chan *CodeError
  104. lastErr *CodeError
  105. }
  106. func NewBidChanServer[Recv, Send any](svr BidChannelAPIServer, errChan chan *CodeError) BidChan[Recv, Send] {
  107. return &bidChanServer[Recv, Send]{svr: svr, errChan: errChan}
  108. }
  109. func (s *bidChanServer[Recv, Send]) Send(val Send) *CodeError {
  110. if s.lastErr != nil {
  111. return s.lastErr
  112. }
  113. data, err := serder.ObjectToJSONEx(val)
  114. if err != nil {
  115. s.lastErr = Failed(ecode.OperationFailed, err.Error())
  116. s.errChan <- s.lastErr
  117. return Failed(ecode.OperationFailed, err.Error())
  118. }
  119. err = s.svr.Send(&Response{Payload: data})
  120. if err != nil {
  121. s.lastErr = getCodeError(err)
  122. s.errChan <- s.lastErr
  123. return s.lastErr
  124. }
  125. return nil
  126. }
  127. func (s *bidChanServer[Recv, Send]) Receive() (Recv, *CodeError) {
  128. if s.lastErr != nil {
  129. var def Recv
  130. return def, s.lastErr
  131. }
  132. req, err := s.svr.Recv()
  133. if err != nil {
  134. s.lastErr = getCodeError(err)
  135. s.errChan <- s.lastErr
  136. var def Recv
  137. return def, s.lastErr
  138. }
  139. req2, err := serder.JSONToObjectEx[Recv](req.Payload)
  140. if err != nil {
  141. s.lastErr = Failed(ecode.OperationFailed, err.Error())
  142. s.errChan <- s.lastErr
  143. var def Recv
  144. return def, s.lastErr
  145. }
  146. return req2, nil
  147. }
  148. func (s *bidChanServer[Recv, Send]) Close() {
  149. if s.lastErr != nil {
  150. return
  151. }
  152. s.lastErr = ErrChannelClosed
  153. s.errChan <- nil
  154. }
  155. func (s *bidChanServer[Recv, Send]) CloseWithError(err *CodeError) {
  156. if s.lastErr != nil {
  157. return
  158. }
  159. s.lastErr = err
  160. s.errChan <- err
  161. }

本项目旨在将云际存储公共基础设施化,使个人及企业可低门槛使用高效的云际存储服务(安装开箱即用云际存储客户端即可,无需关注其他组件的部署),同时支持用户灵活便捷定制云际存储的功能细节。