github.com/btccom/go-micro/v2@v2.9.3/broker/service/subscriber.go (about)

     1  package service
     2  
     3  import (
     4  	"github.com/btccom/go-micro/v2/broker"
     5  	pb "github.com/btccom/go-micro/v2/broker/service/proto"
     6  	"github.com/btccom/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  }