github.com/choria-io/go-choria@v0.28.1-0.20240416190746-b3bf9c7d5a45/broker/federation/choria_nats_ingest.go (about) 1 // Copyright (c) 2017-2022, 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/choria-io/go-choria/inter" 13 "github.com/prometheus/client_golang/prometheus" 14 log "github.com/sirupsen/logrus" 15 ) 16 17 func NewChoriaNatsIngest(workers int, mode int, capacity int, broker *FederationBroker, logger *log.Entry) (*pooledWorker, error) { 18 worker, err := PooledWorkerFactory("choria_nats_ingest", workers, mode, capacity, broker, logger, func(ctx context.Context, self *pooledWorker, i int, logger *log.Entry) { 19 defer self.wg.Done() 20 21 nc, err := self.connection.NewConnector(ctx, self.servers, self.Name(), logger) 22 if err != nil { 23 logger.Errorf("Could not start NATS connection for worker %d: %s", i, err) 24 return 25 } 26 27 var grp, subj string 28 29 switch self.mode { 30 case Federation: 31 subj = fmt.Sprintf("choria.federation.%s.federation", self.broker.Name) 32 grp = fmt.Sprintf("%s_federation", self.broker.Name) 33 case Collective: 34 subj = fmt.Sprintf("choria.federation.%s.collective", self.broker.Name) 35 grp = fmt.Sprintf("%s_collective", self.broker.Name) 36 } 37 38 natsch, err := nc.ChanQueueSubscribe("ingest", subj, grp, 64) 39 if err != nil { 40 logger.Errorf("Could not subscribe to %s: %s", subj, err) 41 return 42 } 43 44 workeri := fmt.Sprintf("%d", i) 45 mname := nameForConnectionMode(mode) 46 ctr := stats.ReceivedMsgsCtr.WithLabelValues("nats_ingest", workeri, mname, self.broker.Name, self.broker.identity) 47 ectr := stats.ErrorCtr.WithLabelValues("nats_ingest", workeri, mname, self.broker.Name, self.broker.identity) 48 timer := stats.ProcessTime.WithLabelValues("nats_ingest", workeri, mname, self.broker.Name, self.broker.identity) 49 50 handler := func(msg inter.ConnectorMessage) { 51 obs := prometheus.NewTimer(timer) 52 defer obs.ObserveDuration() 53 54 message, err := self.choria.NewTransportFromJSON(msg.Data()) 55 if err != nil { 56 logger.Warnf("Could not parse received message into a TransportMessage: %s", err) 57 ectr.Inc() 58 return 59 } 60 61 reqid, federated := message.FederationRequestID() 62 if !federated { 63 logger.Warnf("Received a message on %s that was not federated", msg.Subject()) 64 ectr.Inc() 65 return 66 } 67 68 cm := chainmessage{ 69 Message: message, 70 RequestID: reqid, 71 Seen: []string{nc.ConnectedServer(), fmt.Sprintf("%s:%d", self.Name(), i)}, 72 } 73 74 logger.Debugf("Received message %s via %s", reqid, message.SenderID()) 75 76 self.out <- cm 77 ctr.Inc() 78 } 79 80 for { 81 var msg inter.ConnectorMessage 82 83 select { 84 case msg = <-natsch: 85 handler(msg) 86 87 case <-ctx.Done(): 88 logger.Infof("Worker routine %s exiting", self.Name()) 89 return 90 } 91 } 92 }) 93 94 return worker, err 95 }