|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- package rpc
-
- import (
- "gitlink.org.cn/cloudream/common/utils/serder"
- "gitlink.org.cn/cloudream/jcs-pub/common/ecode"
- )
-
- var ErrChannelClosed = Failed(ecode.ChannelClosed, "channel closed")
-
- type ChanSender[T any] interface {
- Send(val T) *CodeError
- Close()
- // 关闭连接,并发送错误码。注意:客户端部分的Channel调用此函数时设置的err不会被送到服务端,因为GRPC没有提供这样的机制。
- CloseWithError(err *CodeError)
- }
-
- type ChanReceiver[T any] interface {
- Receive() (T, *CodeError)
- Close()
- // 关闭连接,并发送错误码。注意:客户端部分的Channel调用此函数时设置的err不会被送到服务端,因为GRPC没有提供这样的机制。
- CloseWithError(err *CodeError)
- }
-
- type BidChan[Recv, Send any] interface {
- ChanSender[Send]
- ChanReceiver[Recv]
- }
-
- type fusedChannel[Recv, Send any] struct {
- err *CodeError
- }
-
- func (f *fusedChannel[Recv, Send]) Receive() (Recv, *CodeError) {
- var val Recv
- return val, f.err
- }
- func (f *fusedChannel[Recv, Send]) Send(val Send) *CodeError {
- return f.err
- }
- func (f *fusedChannel[Recv, Send]) Close() {
- }
- func (f *fusedChannel[Recv, Send]) CloseWithError(err *CodeError) {
- }
-
- func NewFusedChan[Recv, Send any](err *CodeError) BidChan[Recv, Send] {
- return &fusedChannel[Recv, Send]{err: err}
- }
-
- type bidChanClient[Recv, Send any] struct {
- cli BidChannelAPIClient
- cancelFn func()
- lastErr *CodeError
- }
-
- func NewBidChanClient[Recv, Send any](cli BidChannelAPIClient, cancelFn func()) BidChan[Recv, Send] {
- return &bidChanClient[Recv, Send]{cli: cli, cancelFn: cancelFn}
- }
-
- func (c *bidChanClient[Recv, Send]) Send(val Send) *CodeError {
- if c.lastErr != nil {
- return c.lastErr
- }
-
- data, err := serder.ObjectToJSONEx(val)
- if err != nil {
- c.cancelFn()
- c.lastErr = Failed(ecode.OperationFailed, err.Error())
- return Failed(ecode.OperationFailed, err.Error())
- }
-
- err = c.cli.Send(&Request{Payload: data})
- if err != nil {
- c.cancelFn()
- c.lastErr = getCodeError(err)
- return c.lastErr
- }
-
- return nil
- }
-
- func (c *bidChanClient[Recv, Send]) Receive() (Recv, *CodeError) {
- if c.lastErr != nil {
- var def Recv
- return def, c.lastErr
- }
-
- resp, err := c.cli.Recv()
- if err != nil {
- c.cancelFn()
- c.lastErr = getCodeError(err)
- var def Recv
- return def, c.lastErr
- }
-
- resp2, err := serder.JSONToObjectEx[Recv](resp.Payload)
- if err != nil {
- c.cancelFn()
- c.lastErr = Failed(ecode.OperationFailed, err.Error())
- var def Recv
- return def, c.lastErr
- }
-
- return resp2, nil
- }
-
- func (c *bidChanClient[Recv, Send]) Close() {
- if c.lastErr != nil {
- return
- }
-
- c.cli.CloseSend()
- c.lastErr = ErrChannelClosed
- }
-
- func (c *bidChanClient[Recv, Send]) CloseWithError(err *CodeError) {
- if c.lastErr != nil {
- return
- }
-
- c.cancelFn()
- c.lastErr = err
- }
-
- type bidChanServer[Recv, Send any] struct {
- svr BidChannelAPIServer
- errChan chan *CodeError
- lastErr *CodeError
- }
-
- func NewBidChanServer[Recv, Send any](svr BidChannelAPIServer, errChan chan *CodeError) BidChan[Recv, Send] {
- return &bidChanServer[Recv, Send]{svr: svr, errChan: errChan}
- }
-
- func (s *bidChanServer[Recv, Send]) Send(val Send) *CodeError {
- if s.lastErr != nil {
- return s.lastErr
- }
-
- data, err := serder.ObjectToJSONEx(val)
- if err != nil {
- s.lastErr = Failed(ecode.OperationFailed, err.Error())
- s.errChan <- s.lastErr
- return Failed(ecode.OperationFailed, err.Error())
- }
- err = s.svr.Send(&Response{Payload: data})
- if err != nil {
- s.lastErr = getCodeError(err)
- s.errChan <- s.lastErr
- return s.lastErr
- }
-
- return nil
- }
-
- func (s *bidChanServer[Recv, Send]) Receive() (Recv, *CodeError) {
- if s.lastErr != nil {
- var def Recv
- return def, s.lastErr
- }
-
- req, err := s.svr.Recv()
- if err != nil {
- s.lastErr = getCodeError(err)
- s.errChan <- s.lastErr
- var def Recv
- return def, s.lastErr
- }
-
- req2, err := serder.JSONToObjectEx[Recv](req.Payload)
- if err != nil {
- s.lastErr = Failed(ecode.OperationFailed, err.Error())
- s.errChan <- s.lastErr
- var def Recv
- return def, s.lastErr
- }
-
- return req2, nil
- }
- func (s *bidChanServer[Recv, Send]) Close() {
- if s.lastErr != nil {
- return
- }
-
- s.lastErr = ErrChannelClosed
- s.errChan <- nil
- }
-
- func (s *bidChanServer[Recv, Send]) CloseWithError(err *CodeError) {
- if s.lastErr != nil {
- return
- }
-
- s.lastErr = err
- s.errChan <- err
- }
|