2020-03-06 17:40:47 +03:00
|
|
|
// Package stream encapsulates streams within streams
|
2023-04-11 22:20:37 +03:00
|
|
|
package stream // import "go.unistack.org/micro/v4/util/stream"
|
2020-03-06 17:40:47 +03:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"sync"
|
|
|
|
|
2023-04-11 22:20:37 +03:00
|
|
|
"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 17:40:47 +03:00
|
|
|
)
|
|
|
|
|
2021-02-14 16:16:01 +03:00
|
|
|
// Stream interface
|
2020-03-06 17:40:47 +03:00
|
|
|
type Stream interface {
|
|
|
|
Context() context.Context
|
2021-02-14 16:16:01 +03:00
|
|
|
SendMsg(msg interface{}) error
|
|
|
|
RecvMsg(msg interface{}) error
|
2020-03-06 17:40:47 +03:00
|
|
|
Close() error
|
|
|
|
}
|
|
|
|
|
|
|
|
type stream struct {
|
2022-03-30 15:37:02 +03:00
|
|
|
sync.RWMutex
|
2020-03-06 17:40:47 +03:00
|
|
|
Stream
|
|
|
|
err error
|
|
|
|
request *request
|
|
|
|
}
|
|
|
|
|
|
|
|
type request struct {
|
|
|
|
client.Request
|
|
|
|
context context.Context
|
|
|
|
}
|
|
|
|
|
2021-02-14 16:16:01 +03:00
|
|
|
// Codec returns codec.Codec
|
2020-11-23 16:18:47 +03:00
|
|
|
func (r *request) Codec() codec.Codec {
|
|
|
|
return r.Request.Codec()
|
2020-03-06 17:40:47 +03:00
|
|
|
}
|
|
|
|
|
2021-02-14 16:16:01 +03:00
|
|
|
// Header returns metadata header
|
2020-11-18 16:50:41 +03:00
|
|
|
func (r *request) Header() metadata.Metadata {
|
2021-02-13 01:46:16 +03:00
|
|
|
md, _ := metadata.FromIncomingContext(r.context)
|
2020-03-06 17:40:47 +03:00
|
|
|
return md
|
|
|
|
}
|
|
|
|
|
2021-02-14 16:16:01 +03:00
|
|
|
// Read returns stream data
|
2020-03-06 17:40:47 +03:00
|
|
|
func (r *request) Read() ([]byte, error) {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
2021-02-14 16:16:01 +03:00
|
|
|
// Request returns server.Request
|
2020-03-06 17:40:47 +03:00
|
|
|
func (s *stream) Request() server.Request {
|
|
|
|
return s.request
|
|
|
|
}
|
|
|
|
|
2021-02-14 16:16:01 +03:00
|
|
|
// Send sends message
|
2020-03-06 17:40:47 +03: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
|
|
|
|
}
|
|
|
|
|
2021-02-14 16:16:01 +03:00
|
|
|
// Recv receives data
|
2020-03-06 17:40:47 +03: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
|
|
|
|
}
|
|
|
|
|
2021-02-14 16:16:01 +03:00
|
|
|
// Error returns error that stream holds
|
2020-03-06 17:40:47 +03: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
|
2020-08-25 13:44:41 +03:00
|
|
|
func New(service, endpoint string, req interface{}, c client.Client, s Stream) server.Stream {
|
2020-03-06 17:40:47 +03:00
|
|
|
return &stream{
|
|
|
|
Stream: s,
|
|
|
|
request: &request{
|
|
|
|
context: s.Context(),
|
2020-08-25 13:44:41 +03:00
|
|
|
Request: c.NewRequest(service, endpoint, req),
|
2020-03-06 17:40:47 +03:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|