github.com/annwntech/go-micro/v2@v2.9.5/broker/service/subscriber.go (about) 1 package service 2 3 import ( 4 "github.com/annwntech/go-micro/v2/broker" 5 pb "github.com/annwntech/go-micro/v2/broker/service/proto" 6 "github.com/annwntech/go-micro/v2/logger" 7 ) 8 9 type serviceSub struct { 10 topic string 11 queue string 12 handler broker.Handler 13 stream pb.Broker_SubscribeService 14 closed chan bool 15 options broker.SubscribeOptions 16 } 17 18 type serviceEvent struct { 19 topic string 20 err error 21 message *broker.Message 22 } 23 24 func (s *serviceEvent) Topic() string { 25 return s.topic 26 } 27 28 func (s *serviceEvent) Message() *broker.Message { 29 return s.message 30 } 31 32 func (s *serviceEvent) Ack() error { 33 return nil 34 } 35 36 func (s *serviceEvent) Error() error { 37 return s.err 38 } 39 40 func (s *serviceSub) isClosed() bool { 41 select { 42 case <-s.closed: 43 return true 44 default: 45 return false 46 } 47 } 48 49 func (s *serviceSub) run() error { 50 exit := make(chan bool) 51 go func() { 52 select { 53 case <-exit: 54 case <-s.closed: 55 } 56 57 // close the stream 58 s.stream.Close() 59 }() 60 61 for { 62 // TODO: do not fail silently 63 msg, err := s.stream.Recv() 64 if err != nil { 65 if logger.V(logger.DebugLevel, logger.DefaultLogger) { 66 logger.Debugf("Streaming error for subcription to topic %s: %v", s.Topic(), err) 67 } 68 69 // close the exit channel 70 close(exit) 71 72 // don't return an error if we unsubscribed 73 if s.isClosed() { 74 return nil 75 } 76 77 // return stream error 78 return err 79 } 80 81 p := &serviceEvent{ 82 topic: s.topic, 83 message: &broker.Message{ 84 Header: msg.Header, 85 Body: msg.Body, 86 }, 87 } 88 p.err = s.handler(p) 89 } 90 } 91 92 func (s *serviceSub) Options() broker.SubscribeOptions { 93 return s.options 94 } 95 96 func (s *serviceSub) Topic() string { 97 return s.topic 98 } 99 100 func (s *serviceSub) Unsubscribe() error { 101 select { 102 case <-s.closed: 103 return nil 104 default: 105 close(s.closed) 106 } 107 return nil 108 }