github.com/annwntech/go-micro/v2@v2.9.5/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/annwntech/go-micro/v2/broker" 9 pb "github.com/annwntech/go-micro/v2/broker/service/proto" 10 "github.com/annwntech/go-micro/v2/client" 11 "github.com/annwntech/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 }