github.com/choria-io/go-choria@v0.28.1-0.20240416190746-b3bf9c7d5a45/broker/federation/reply_transformer.go (about) 1 // Copyright (c) 2017-2021, R.I. Pienaar and the Choria Project contributors 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 5 package federation 6 7 import ( 8 "context" 9 "fmt" 10 11 "github.com/choria-io/go-choria/broker/federation/stats" 12 "github.com/prometheus/client_golang/prometheus" 13 log "github.com/sirupsen/logrus" 14 ) 15 16 func NewChoriaReplyTransformer(workers int, capacity int, broker *FederationBroker, logger *log.Entry) (*pooledWorker, error) { 17 worker, err := PooledWorkerFactory("choria_reply_transformer", workers, Unconnected, capacity, broker, logger, func(ctx context.Context, self *pooledWorker, i int, logger *log.Entry) { 18 defer self.wg.Done() 19 20 workeri := fmt.Sprintf("%d", i) 21 rctr := stats.ReceivedMsgsCtr.WithLabelValues("choria_reply_transformer", workeri, nameForConnectionMode(Unconnected), self.broker.Name, self.broker.identity) 22 ectr := stats.ErrorCtr.WithLabelValues("choria_reply_transformer", workeri, nameForConnectionMode(Unconnected), self.broker.Name, self.broker.identity) 23 timer := stats.ProcessTime.WithLabelValues("choria_reply_transformer", workeri, nameForConnectionMode(Unconnected), self.broker.Name, self.broker.identity) 24 25 transf := func(cm chainmessage) { 26 obs := prometheus.NewTimer(timer) 27 defer obs.ObserveDuration() 28 29 req, federated := cm.Message.FederationRequestID() 30 if !federated { 31 logger.Errorf("Received a message from %s that is not federated", cm.Message.SenderID()) 32 ectr.Inc() 33 return 34 } 35 36 replyto, _ := cm.Message.FederationReplyTo() 37 if replyto == "" { 38 logger.Errorf("Received message %s with no reply-to set", req) 39 ectr.Inc() 40 return 41 } 42 43 cm.Seen = append(cm.Seen, fmt.Sprintf("%s:%d", self.Name(), i)) 44 cm.Targets = []string{replyto} 45 cm.RequestID = req 46 47 cm.Message.SetUnfederated() 48 49 logger.Debugf("Received a reply message '%s' via %s", cm.RequestID, cm.Message.SenderID()) 50 51 self.out <- cm 52 53 rctr.Inc() 54 } 55 56 for { 57 var cm chainmessage 58 59 select { 60 case cm = <-self.in: 61 transf(cm) 62 case <-ctx.Done(): 63 logger.Infof("Worker routine %s exiting", self.Name()) 64 return 65 } 66 67 } 68 }) 69 70 return worker, err 71 }