milvus/internal/util/streamrpc/streamer.go
jaime 7f7c71ea7d
Decoupling client and server API in types interface (#27186)
Co-authored-by:: aoiasd <zhicheng.yue@zilliz.com>

Signed-off-by: jaime <yun.zhang@zilliz.com>
2023-09-26 09:57:25 +08:00

138 lines
2.6 KiB
Go

package streamrpc
import (
"context"
"io"
"sync"
"google.golang.org/grpc"
"github.com/milvus-io/milvus/internal/proto/internalpb"
)
type QueryStreamServer interface {
Send(*internalpb.RetrieveResults) error
Context() context.Context
}
type QueryStreamClient interface {
Recv() (*internalpb.RetrieveResults, error)
Context() context.Context
CloseSend() error
}
type ConcurrentQueryStreamServer struct {
server QueryStreamServer
mu sync.Mutex
}
func (s *ConcurrentQueryStreamServer) Send(result *internalpb.RetrieveResults) error {
s.mu.Lock()
defer s.mu.Unlock()
return s.server.Send(result)
}
func (s *ConcurrentQueryStreamServer) Context() context.Context {
return s.server.Context()
}
func NewConcurrentQueryStreamServer(srv QueryStreamServer) *ConcurrentQueryStreamServer {
return &ConcurrentQueryStreamServer{
server: srv,
mu: sync.Mutex{},
}
}
// TODO LOCAL SERVER AND CLIENT FOR STANDALONE
// ONLY FOR TEST
type LocalQueryServer struct {
grpc.ServerStream
resultCh chan *internalpb.RetrieveResults
ctx context.Context
finishOnce sync.Once
errCh chan error
mu sync.Mutex
}
func (s *LocalQueryServer) Send(result *internalpb.RetrieveResults) error {
select {
case <-s.ctx.Done():
return s.ctx.Err()
default:
s.resultCh <- result
return nil
}
}
func (s *LocalQueryServer) FinishError() error {
return <-s.errCh
}
func (s *LocalQueryServer) Context() context.Context {
return s.ctx
}
func (s *LocalQueryServer) FinishSend(err error) error {
s.finishOnce.Do(func() {
close(s.resultCh)
if err != nil {
s.errCh <- err
} else {
s.errCh <- io.EOF
}
})
return nil
}
type LocalQueryClient struct {
grpc.ClientStream
server *LocalQueryServer
resultCh chan *internalpb.RetrieveResults
ctx context.Context
}
func (s *LocalQueryClient) RecvMsg(m interface{}) error {
// TODO implement me
panic("implement me")
}
func (s *LocalQueryClient) Recv() (*internalpb.RetrieveResults, error) {
select {
case <-s.ctx.Done():
return nil, s.ctx.Err()
default:
result, ok := <-s.resultCh
if !ok {
return nil, s.server.FinishError()
}
return result, nil
}
}
func (s *LocalQueryClient) Context() context.Context {
return s.ctx
}
func (s *LocalQueryClient) CloseSend() error {
return nil
}
func (s *LocalQueryClient) CreateServer() *LocalQueryServer {
s.server = &LocalQueryServer{
resultCh: s.resultCh,
ctx: s.ctx,
mu: sync.Mutex{},
errCh: make(chan error, 1),
}
return s.server
}
func NewLocalQueryClient(ctx context.Context) *LocalQueryClient {
return &LocalQueryClient{
resultCh: make(chan *internalpb.RetrieveResults, 64),
ctx: ctx,
}
}