micro/util/stream/stream.go

95 lines
1.7 KiB
Go
Raw Normal View History

2020-03-06 14:40:47 +00:00
// Package stream encapsulates streams within streams
package stream // import "go.unistack.org/micro/v4/util/stream"
2020-03-06 14:40:47 +00:00
import (
"context"
"sync"
"go.unistack.org/micro/v4/client"
"go.unistack.org/micro/v4/codec"
"go.unistack.org/micro/v4/metadata"
"go.unistack.org/micro/v4/server"
2020-03-06 14:40:47 +00:00
)
// Stream interface
2020-03-06 14:40:47 +00:00
type Stream interface {
Context() context.Context
SendMsg(msg interface{}) error
RecvMsg(msg interface{}) error
2020-03-06 14:40:47 +00:00
Close() error
}
type stream struct {
sync.RWMutex
2020-03-06 14:40:47 +00:00
Stream
err error
request *request
}
type request struct {
client.Request
context context.Context
}
// Codec returns codec.Codec
func (r *request) Codec() codec.Codec {
return r.Request.Codec()
2020-03-06 14:40:47 +00:00
}
// Header returns metadata header
func (r *request) Header() metadata.Metadata {
md, _ := metadata.FromIncomingContext(r.context)
2020-03-06 14:40:47 +00:00
return md
}
// Read returns stream data
2020-03-06 14:40:47 +00:00
func (r *request) Read() ([]byte, error) {
return nil, nil
}
// Request returns server.Request
2020-03-06 14:40:47 +00:00
func (s *stream) Request() server.Request {
return s.request
}
// Send sends message
2020-03-06 14:40:47 +00:00
func (s *stream) Send(v interface{}) error {
err := s.Stream.SendMsg(v)
if err != nil {
s.Lock()
s.err = err
s.Unlock()
}
return err
}
// Recv receives data
2020-03-06 14:40:47 +00:00
func (s *stream) Recv(v interface{}) error {
err := s.Stream.RecvMsg(v)
if err != nil {
s.Lock()
s.err = err
s.Unlock()
}
return err
}
// Error returns error that stream holds
2020-03-06 14:40:47 +00:00
func (s *stream) Error() error {
s.RLock()
defer s.RUnlock()
return s.err
}
// New returns a new encapsulated stream
// Proto stream within a server.Stream
func New(service, endpoint string, req interface{}, c client.Client, s Stream) server.Stream {
2020-03-06 14:40:47 +00:00
return &stream{
Stream: s,
request: &request{
context: s.Context(),
Request: c.NewRequest(service, endpoint, req),
2020-03-06 14:40:47 +00:00
},
}
}