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  }