feat: subscribe to RabbitMQ trade signals and notify by rules
Consume configurable queues, format signals (including period), share NotifyService with HTTP, and drop duplicate bodies within 1h.
This commit is contained in:
+31
-7
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
@@ -15,8 +16,11 @@ import (
|
||||
"aiaa-notification-service/internal/config"
|
||||
"aiaa-notification-service/internal/engine"
|
||||
"aiaa-notification-service/internal/handler"
|
||||
"aiaa-notification-service/internal/model"
|
||||
"aiaa-notification-service/internal/notify"
|
||||
"aiaa-notification-service/internal/safew"
|
||||
"aiaa-notification-service/internal/store"
|
||||
"aiaa-notification-service/internal/subscriber"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/logbull/logbull-go/logbull"
|
||||
@@ -123,7 +127,8 @@ func main() {
|
||||
router := engine.NewRouter(st, redisCache, senderFactory)
|
||||
|
||||
// Build handlers
|
||||
notifyH := handler.NewNotifyHandler(st, redisCache, matcher, renderer, router)
|
||||
notifySvc := notify.NewService(matcher, st, renderer, router, st)
|
||||
notifyH := handler.NewNotifyHandler(notifySvc)
|
||||
sourceH := handler.NewSourceHandler(st, redisCache)
|
||||
templateH := handler.NewTemplateHandler(st, redisCache)
|
||||
|
||||
@@ -217,6 +222,28 @@ func main() {
|
||||
Handler: r,
|
||||
}
|
||||
|
||||
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
lookup := func(ctx context.Context, name string) (*model.Source, error) {
|
||||
return st.GetSourceByName(ctx, name)
|
||||
}
|
||||
deduper := subscriber.NewCacheDeduper(redisCache, cfg.SubscriptionDedupTTL)
|
||||
for _, sub := range cfg.ActiveSubscriptions() {
|
||||
sub := sub
|
||||
cons, err := subscriber.New(sub, lookup, notifySvc.Process, deduper)
|
||||
if err != nil {
|
||||
slog.Error("subscriber init", "name", sub.Name, "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
go func() {
|
||||
if err := cons.Run(ctx); err != nil && !errors.Is(err, context.Canceled) {
|
||||
slog.Error("subscriber stopped", "name", sub.Name, "error", err)
|
||||
}
|
||||
}()
|
||||
slog.Info("subscriber started", "name", sub.Name, "queue", sub.Queue, "source", sub.Source)
|
||||
}
|
||||
|
||||
go func() {
|
||||
slog.Info("server starting", "port", cfg.Server.Port)
|
||||
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
@@ -225,15 +252,12 @@ func main() {
|
||||
}
|
||||
}()
|
||||
|
||||
// Graceful shutdown
|
||||
quit := make(chan os.Signal, 1)
|
||||
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-quit
|
||||
<-ctx.Done()
|
||||
slog.Info("shutting down...")
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
if err := srv.Shutdown(ctx); err != nil {
|
||||
if err := srv.Shutdown(shutdownCtx); err != nil {
|
||||
slog.Error("forced shutdown", "error", err)
|
||||
}
|
||||
slog.Info("server stopped")
|
||||
|
||||
Reference in New Issue
Block a user