github.com/choria-io/go-choria@v0.28.1-0.20240416190746-b3bf9c7d5a45/broker/federation/request_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 NewChoriaRequestTransformer(workers int, capacity int, broker *FederationBroker, logger *log.Entry) (*pooledWorker, error) { 17 worker, err := PooledWorkerFactory("choria_request_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_request_transformer", workeri, nameForConnectionMode(Unconnected), self.broker.Name, self.broker.identity) 22 ectr := stats.ErrorCtr.WithLabelValues("choria_request_transformer", workeri, nameForConnectionMode(Unconnected), self.broker.Name, self.broker.identity) 23 timer := stats.ProcessTime.WithLabelValues("choria_request_transformer", workeri, nameForConnectionMode(Unconnected), self.broker.Name, self.broker.identity) 24 25 workerf := 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 targets, _ := cm.Message.FederationTargets() 37 if len(targets) == 0 { 38 logger.Errorf("Received a message %s from %s that does not have any targets", req, cm.Message.SenderID()) 39 ectr.Inc() 40 return 41 } 42 43 replyto := cm.Message.ReplyTo() 44 if replyto == "" { 45 logger.Errorf("Received a message %s with no reply-to set", req) 46 ectr.Inc() 47 return 48 } 49 50 cm.Seen = append(cm.Seen, fmt.Sprintf("%s:%d", self.Name(), i)) 51 cm.RequestID = req 52 cm.Targets = targets 53 54 cm.Message.SetFederationTargets([]string{}) 55 cm.Message.SetFederationReplyTo(replyto) 56 cm.Message.SetReplyTo(fmt.Sprintf("choria.federation.%s.collective", self.broker.Name)) 57 58 logger.Infof("Received request message '%s' via %s with %d targets", cm.RequestID, cm.Message.SenderID(), len(cm.Targets)) 59 60 self.out <- cm 61 62 rctr.Inc() 63 } 64 65 for { 66 var cm chainmessage 67 68 select { 69 case cm = <-self.in: 70 workerf(cm) 71 case <-ctx.Done(): 72 logger.Infof("Worker routine %s exiting", self.Name()) 73 return 74 } 75 76 } 77 }) 78 79 return worker, err 80 }