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

     1  // Package service provides the broker service client
     2  package service
     3  
     4  import (
     5  	"context"
     6  	"time"
     7  
     8  	"github.com/btccom/go-micro/v2/broker"
     9  	pb "github.com/btccom/go-micro/v2/broker/service/proto"
    10  	"github.com/btccom/go-micro/v2/client"
    11  	"github.com/btccom/go-micro/v2/logger"
    12  )
    13  
    14  type serviceBroker struct {
    15  	Addrs   []string
    16  	Client  pb.BrokerService
    17  	options broker.Options
    18  }
    19  
    20  var (
    21  	DefaultName = "go.micro.broker"
    22  )
    23  
    24  func (b *serviceBroker) Address() string {
    25  	return b.Addrs[0]
    26  }
    27  
    28  func (b *serviceBroker) Connect() error {
    29  	return nil
    30  }
    31  
    32  func (b *serviceBroker) Disconnect() error {
    33  	return nil
    34  }
    35  
    36  func (b *serviceBroker) Init(opts ...broker.Option) error {
    37  	for _, o := range opts {
    38  		o(&b.options)
    39  	}
    40  	return nil
    41  }
    42  
    43  func (b *serviceBroker) Options() broker.Options {
    44  	return b.options
    45  }
    46  
    47  func (b *serviceBroker) Publish(topic string, msg *broker.Message, opts ...broker.PublishOption) error {
    48  	if logger.V(logger.DebugLevel, logger.DefaultLogger) {
    49  		logger.Debugf("Publishing to topic %s broker %v", topic, b.Addrs)
    50  	}
    51  	_, err := b.Client.Publish(context.TODO(), &pb.PublishRequest{
    52  		Topic: topic,
    53  		Message: &pb.Message{
    54  			Header: msg.Header,
    55  			Body:   msg.Body,
    56  		},
    57  	}, client.WithAddress(b.Addrs...))
    58  	return err
    59  }
    60  
    61  func (b *serviceBroker) Subscribe(topic string, handler broker.Handler, opts ...broker.SubscribeOption) (broker.Subscriber, error) {
    62  	var options broker.SubscribeOptions
    63  	for _, o := range opts {
    64  		o(&options)
    65  	}
    66  	if logger.V(logger.DebugLevel, logger.DefaultLogger) {
    67  		logger.Debugf("Subscribing to topic %s queue %s broker %v", topic, options.Queue, b.Addrs)
    68  	}
    69  	stream, err := b.Client.Subscribe(context.TODO(), &pb.SubscribeRequest{
    70  		Topic: topic,
    71  		Queue: options.Queue,
    72  	}, client.WithAddress(b.Addrs...), client.WithRequestTimeout(time.Hour))
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  
    77  	sub := &serviceSub{
    78  		topic:   topic,
    79  		queue:   options.Queue,
    80  		handler: handler,
    81  		stream:  stream,
    82  		closed:  make(chan bool),
    83  		options: options,
    84  	}
    85  
    86  	go func() {
    87  		for {
    88  			select {
    89  			case <-sub.closed:
    90  				if logger.V(logger.DebugLevel, logger.DefaultLogger) {
    91  					logger.Debugf("Unsubscribed from topic %s", topic)
    92  				}
    93  				return
    94  			default:
    95  				if logger.V(logger.DebugLevel, logger.DefaultLogger) {
    96  					// run the subscriber
    97  					logger.Debugf("Streaming from broker %v to topic [%s] queue [%s]", b.Addrs, topic, options.Queue)
    98  				}
    99  				if err := sub.run(); err != nil {
   100  					if logger.V(logger.DebugLevel, logger.DefaultLogger) {
   101  						logger.Debugf("Resubscribing to topic %s broker %v", topic, b.Addrs)
   102  					}
   103  					stream, err := b.Client.Subscribe(context.TODO(), &pb.SubscribeRequest{
   104  						Topic: topic,
   105  						Queue: options.Queue,
   106  					}, client.WithAddress(b.Addrs...), client.WithRequestTimeout(time.Hour))
   107  					if err != nil {
   108  						if logger.V(logger.DebugLevel, logger.DefaultLogger) {
   109  							logger.Debugf("Failed to resubscribe to topic %s: %v", topic, err)
   110  						}
   111  						time.Sleep(time.Second)
   112  						continue
   113  					}
   114  					// new stream
   115  					sub.stream = stream
   116  				}
   117  			}
   118  		}
   119  	}()
   120  
   121  	return sub, nil
   122  }
   123  
   124  func (b *serviceBroker) String() string {
   125  	return "service"
   126  }
   127  
   128  func NewBroker(opts ...broker.Option) broker.Broker {
   129  	var options broker.Options
   130  	for _, o := range opts {
   131  		o(&options)
   132  	}
   133  
   134  	addrs := options.Addrs
   135  	if len(addrs) == 0 {
   136  		addrs = []string{"127.0.0.1:8001"}
   137  	}
   138  
   139  	cli := client.DefaultClient
   140  
   141  	return &serviceBroker{
   142  		Addrs:   addrs,
   143  		Client:  pb.NewBrokerService(DefaultName, cli),
   144  		options: options,
   145  	}
   146  }