update handler (#2)

* 🔧 Remove commented-out regex patterns and initialization in config.

*  Add NATS message publisher with configuration 📩🚀

*  Add new PlainTextMarshaler and refactor handler in nats package.
This commit is contained in:
windyboy
2024-08-12 17:47:34 +08:00
committed by GitHub
parent fd58395db3
commit 8a4c46aa34
6 changed files with 82 additions and 20 deletions
+2 -3
View File
@@ -2,7 +2,6 @@ package main
import ( import (
"caatsm/internal/config" "caatsm/internal/config"
"caatsm/internal/handlers"
"caatsm/internal/nats" "caatsm/internal/nats"
"caatsm/pkg/utils" "caatsm/pkg/utils"
"os" "os"
@@ -83,7 +82,7 @@ func executeListen(c *cli.Context) error {
fmt.Println("Loaded configuration successfully") fmt.Println("Loaded configuration successfully")
log := utils.GetLogger() log := utils.GetLogger()
log.Info("Starting nats subscriber") log.Info("Starting nats subscriber")
handler := handlers.New(cfg) // handler := handlers.New(cfg)
nats.Subscribe(cfg, &handlers.PlainTextMarshaler{}, handler) nats.Subscribe(cfg, &nats.PlainTextMarshaler{})
return nil return nil
} }
+3
View File
@@ -7,6 +7,9 @@ cluster = "tele-cluster"
topic = "Telegram.Serial" topic = "Telegram.Serial"
queue = "tele-queue" queue = "tele-queue"
[publisher]
topic = "Telegram.Json"
[timeouts] [timeouts]
server = "5s" server = "5s"
reconnect_wait = "5s" reconnect_wait = "5s"
+5
View File
@@ -15,6 +15,7 @@ var MyConfig *Config
type Config struct { type Config struct {
Nats NatsConfig Nats NatsConfig
Subscription SubscriptionConfig Subscription SubscriptionConfig
Publisher PublisherConfig
Timeouts TimeoutsConfig Timeouts TimeoutsConfig
Hasura HasuraConfig Hasura HasuraConfig
} }
@@ -30,6 +31,10 @@ type SubscriptionConfig struct {
QueueGroup string `mapstructure:"queue_group"` QueueGroup string `mapstructure:"queue_group"`
} }
type PublisherConfig struct {
Topic string `mapstructure:"topic"`
}
type TimeoutsConfig struct { type TimeoutsConfig struct {
Server time.Duration `mapstructure:"server"` Server time.Duration `mapstructure:"server"`
ReconnectWait time.Duration `mapstructure:"reconnect_wait"` ReconnectWait time.Duration `mapstructure:"reconnect_wait"`
@@ -1,4 +1,4 @@
package handlers package nats
import ( import (
"caatsm/internal/config" "caatsm/internal/config"
@@ -6,13 +6,11 @@ import (
"caatsm/internal/parsers" "caatsm/internal/parsers"
"caatsm/internal/repository" "caatsm/internal/repository"
"caatsm/pkg/utils" "caatsm/pkg/utils"
"errors"
"fmt" "fmt"
"sync" "sync"
"github.com/ThreeDotsLabs/watermill" "github.com/ThreeDotsLabs/watermill"
"github.com/ThreeDotsLabs/watermill/message" "github.com/ThreeDotsLabs/watermill/message"
nc "github.com/nats-io/nats.go"
) )
type MessageHandler struct { type MessageHandler struct {
@@ -44,6 +42,7 @@ func (handler *MessageHandler) HandleMessage(msg *message.Message) error {
log.Infof("parsed [%s]: %v\n", msg.UUID, parsed.ToString()) log.Infof("parsed [%s]: %v\n", msg.UUID, parsed.ToString())
} }
handler.SaveMessage(parsed, msg.UUID) handler.SaveMessage(parsed, msg.UUID)
handler.Publish(parsed)
return nil return nil
} }
@@ -57,16 +56,8 @@ func (n *MessageHandler) SaveMessage(parsed *domain.ParsedMessage, uuid string)
} }
} }
type PlainTextMarshaler struct{} func (n *MessageHandler) Publish(parsed *domain.ParsedMessage) {
if err := Publish(n.config, parsed); err != nil {
func (m *PlainTextMarshaler) Marshal(topic string, msg nc.Msg) ([]byte, error) { utils.GetSugaredLogger().Error("error publishing message", err, map[string]interface{}{"message": parsed})
return msg.Data, nil
} }
func (m *PlainTextMarshaler) Unmarshal(newMsg *nc.Msg) (*message.Message, error) {
if newMsg == nil {
return nil, errors.New("empty message")
}
msg := message.NewMessage(watermill.NewUUID(), newMsg.Data)
return msg, nil
} }
+48
View File
@@ -0,0 +1,48 @@
package nats
import (
"caatsm/internal/config"
"encoding/json"
"github.com/ThreeDotsLabs/watermill"
"github.com/ThreeDotsLabs/watermill-nats/v2/pkg/nats"
"github.com/ThreeDotsLabs/watermill/message"
nc "github.com/nats-io/nats.go"
)
func Publish(config *config.Config, parsedMessage interface{}) error {
logger := watermill.NewStdLogger(false, false)
options := []nc.Option{
nc.RetryOnFailedConnect(true),
nc.Timeout(config.Timeouts.Server),
nc.ReconnectWait(config.Timeouts.ReconnectWait),
}
jsConfig := nats.JetStreamConfig{Disabled: true}
publisher, err := nats.NewPublisher(
nats.PublisherConfig{
URL: config.Nats.URL,
NatsOptions: options,
JetStream: jsConfig,
},
logger,
)
if err != nil {
panic(err)
}
logger.Info("NATS server connected", map[string]interface{}{"url": config.Nats.URL})
logger.Info("Publishing message to NATS topic", map[string]interface{}{"topic": config.Publisher.Topic})
messageText, err := json.Marshal(parsedMessage)
if err != nil {
logger.Error("Failed to marshal message", err, map[string]interface{}{"message": parsedMessage})
}
msg := message.NewMessage(watermill.NewUUID(), []byte(messageText))
err = publisher.Publish(config.Publisher.Topic, msg)
if err != nil {
logger.Error("Failed to publish message to NATS topic", err, map[string]interface{}{"topic": config.Publisher.Topic})
return err
}
return nil
}
+19 -3
View File
@@ -2,15 +2,16 @@ package nats
import ( import (
"caatsm/internal/config" "caatsm/internal/config"
"caatsm/internal/handlers"
"context" "context"
"errors"
"github.com/ThreeDotsLabs/watermill" "github.com/ThreeDotsLabs/watermill"
"github.com/ThreeDotsLabs/watermill-nats/v2/pkg/nats" "github.com/ThreeDotsLabs/watermill-nats/v2/pkg/nats"
"github.com/ThreeDotsLabs/watermill/message"
nc "github.com/nats-io/nats.go" nc "github.com/nats-io/nats.go"
) )
func Subscribe(config *config.Config, marshaler *handlers.PlainTextMarshaler, handler *handlers.MessageHandler) { func Subscribe(config *config.Config, marshaler *PlainTextMarshaler) {
logger := watermill.NewStdLogger(false, false) logger := watermill.NewStdLogger(false, false)
options := []nc.Option{ options := []nc.Option{
nc.RetryOnFailedConnect(true), nc.RetryOnFailedConnect(true),
@@ -44,8 +45,9 @@ func Subscribe(config *config.Config, marshaler *handlers.PlainTextMarshaler, ha
return return
} }
handlers := New(config)
for msg := range messages { for msg := range messages {
if err := handler.HandleMessage(msg); err == nil { if err := handlers.HandleMessage(msg); err == nil {
msg.Ack() msg.Ack()
} else { } else {
logger.Error("Failed to handle message", err, map[string]interface{}{"message": msg}) logger.Error("Failed to handle message", err, map[string]interface{}{"message": msg})
@@ -53,3 +55,17 @@ func Subscribe(config *config.Config, marshaler *handlers.PlainTextMarshaler, ha
} }
} }
} }
type PlainTextMarshaler struct{}
func (m *PlainTextMarshaler) Marshal(topic string, msg nc.Msg) ([]byte, error) {
return msg.Data, nil
}
func (m *PlainTextMarshaler) Unmarshal(newMsg *nc.Msg) (*message.Message, error) {
if newMsg == nil {
return nil, errors.New("empty message")
}
msg := message.NewMessage(watermill.NewUUID(), newMsg.Data)
return msg, nil
}