github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/broker/client/client.go (about)

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