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 }