2019-10-03 16:19:02 +01:00
|
|
|
package service
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/micro/go-micro/broker"
|
|
|
|
pb "github.com/micro/go-micro/broker/service/proto"
|
2019-10-04 16:40:16 +01:00
|
|
|
"github.com/micro/go-micro/util/log"
|
2019-10-03 16:19:02 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
type serviceSub struct {
|
|
|
|
topic string
|
|
|
|
queue string
|
|
|
|
handler broker.Handler
|
|
|
|
stream pb.Broker_SubscribeService
|
|
|
|
closed chan bool
|
|
|
|
options broker.SubscribeOptions
|
|
|
|
}
|
|
|
|
|
|
|
|
type serviceEvent struct {
|
|
|
|
topic string
|
|
|
|
message *broker.Message
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *serviceEvent) Topic() string {
|
|
|
|
return s.topic
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *serviceEvent) Message() *broker.Message {
|
|
|
|
return s.message
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *serviceEvent) Ack() error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-10-04 16:30:03 +01:00
|
|
|
func (s *serviceSub) isClosed() bool {
|
|
|
|
select {
|
|
|
|
case <-s.closed:
|
|
|
|
return true
|
|
|
|
default:
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *serviceSub) run() error {
|
2019-10-03 16:19:02 +01:00
|
|
|
exit := make(chan bool)
|
|
|
|
go func() {
|
|
|
|
select {
|
|
|
|
case <-exit:
|
|
|
|
case <-s.closed:
|
|
|
|
}
|
2019-10-04 16:30:03 +01:00
|
|
|
|
|
|
|
// close the stream
|
|
|
|
s.stream.Close()
|
2019-10-03 16:19:02 +01:00
|
|
|
}()
|
|
|
|
|
|
|
|
for {
|
|
|
|
// TODO: do not fail silently
|
|
|
|
msg, err := s.stream.Recv()
|
|
|
|
if err != nil {
|
2019-10-04 16:30:03 +01:00
|
|
|
log.Debugf("Streaming error for subcription to topic %s: %v", s.Topic(), err)
|
|
|
|
|
|
|
|
// close the exit channel
|
2019-10-03 16:19:02 +01:00
|
|
|
close(exit)
|
2019-10-04 16:30:03 +01:00
|
|
|
|
|
|
|
// don't return an error if we unsubscribed
|
|
|
|
if s.isClosed() {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// return stream error
|
|
|
|
return err
|
2019-10-03 16:19:02 +01:00
|
|
|
}
|
2019-10-04 16:30:03 +01:00
|
|
|
|
2019-10-03 16:19:02 +01:00
|
|
|
// TODO: handle error
|
|
|
|
s.handler(&serviceEvent{
|
|
|
|
topic: s.topic,
|
|
|
|
message: &broker.Message{
|
|
|
|
Header: msg.Header,
|
|
|
|
Body: msg.Body,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *serviceSub) Options() broker.SubscribeOptions {
|
|
|
|
return s.options
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *serviceSub) Topic() string {
|
|
|
|
return s.topic
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *serviceSub) Unsubscribe() error {
|
|
|
|
select {
|
|
|
|
case <-s.closed:
|
|
|
|
return nil
|
|
|
|
default:
|
|
|
|
close(s.closed)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|