github.com/safedep/dry@v0.0.0-20241016050132-a15651f0548b/async/nats.go (about)

     1  package async
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  	"time"
     7  
     8  	"github.com/nats-io/nats.go"
     9  	"github.com/safedep/dry/log"
    10  )
    11  
    12  type NatsMessagingConfig struct {
    13  	NatsURL string
    14  }
    15  
    16  type natsMessaging struct {
    17  	config NatsMessagingConfig
    18  	conn   *nats.Conn
    19  }
    20  
    21  func NewNatsMessagingService(config NatsMessagingConfig) (MessagingService, error) {
    22  	if config.NatsURL == "" {
    23  		config.NatsURL = os.Getenv("NATS_URL")
    24  
    25  		if config.NatsURL == "" {
    26  			config.NatsURL = nats.DefaultURL
    27  		}
    28  	}
    29  
    30  	log.Infof("Connecting to NATS server at %s", config.NatsURL)
    31  
    32  	conn, err := nats.Connect(config.NatsURL,
    33  		nats.RetryOnFailedConnect(true),
    34  		nats.MaxReconnects(-1),
    35  		nats.ReconnectWait(1*time.Second))
    36  
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  
    41  	err = conn.Flush()
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  
    46  	rtt, err := conn.RTT()
    47  	if err != nil {
    48  		return nil, err
    49  	}
    50  
    51  	log.Infof("Connected to NATS server at %s. RTT: %v", config.NatsURL, rtt)
    52  
    53  	return &natsMessaging{
    54  		config: config,
    55  		conn:   conn,
    56  	}, nil
    57  }
    58  
    59  func NewNatsRequestResponseService(config NatsMessagingConfig) (AsyncRequestResponseService, error) {
    60  	messagingService, err := NewNatsMessagingService(config)
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  
    65  	natsMessagingService := messagingService.(*natsMessaging)
    66  	return natsMessagingService, nil
    67  }
    68  
    69  func (n *natsMessaging) Close() error {
    70  	n.conn.Close()
    71  	return nil
    72  }
    73  
    74  func (n *natsMessaging) Publish(_ context.Context, topic string, data []byte) error {
    75  	return n.conn.Publish(topic, data)
    76  }
    77  
    78  func (n *natsMessaging) QueueSubscribe(topic string, queue string, callback MessageHandler) (MessagingQueueSubscription, error) {
    79  	return n.conn.QueueSubscribe(topic, queue, func(m *nats.Msg) {
    80  		err := callback(context.Background(), m.Data)
    81  		if err != nil {
    82  			log.Errorf("Error processing message: %v", err)
    83  		}
    84  	})
    85  }
    86  
    87  func (n *natsMessaging) Request(_ context.Context,
    88  	topic string, data []byte, timeout time.Duration) ([]byte, error) {
    89  	res, err := n.conn.Request(topic, data, timeout)
    90  	if err != nil {
    91  		return nil, err
    92  	}
    93  
    94  	return res.Data, nil
    95  }