fix: wire retry into router, fix Docker config path, fix condition error handling, remove dead code
This commit is contained in:
+1
-1
@@ -10,7 +10,7 @@ FROM alpine:3.20
|
|||||||
|
|
||||||
RUN apk add --no-cache ca-certificates tzdata
|
RUN apk add --no-cache ca-certificates tzdata
|
||||||
COPY --from=builder /server /usr/local/bin/server
|
COPY --from=builder /server /usr/local/bin/server
|
||||||
COPY config/config.yaml /etc/notification/config.yaml
|
COPY config/config.yaml /config/config.yaml
|
||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
ENTRYPOINT ["server"]
|
ENTRYPOINT ["server"]
|
||||||
|
|||||||
@@ -9,16 +9,10 @@ import (
|
|||||||
"aiaa-notification-service/internal/adapter"
|
"aiaa-notification-service/internal/adapter"
|
||||||
"aiaa-notification-service/internal/cache"
|
"aiaa-notification-service/internal/cache"
|
||||||
"aiaa-notification-service/internal/model"
|
"aiaa-notification-service/internal/model"
|
||||||
|
"aiaa-notification-service/internal/retry"
|
||||||
"aiaa-notification-service/internal/store"
|
"aiaa-notification-service/internal/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SendResult struct {
|
|
||||||
ChannelType string `json:"channel_type"`
|
|
||||||
ChannelID int `json:"channel_id"`
|
|
||||||
Success bool `json:"success"`
|
|
||||||
Error string `json:"error,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Router struct {
|
type Router struct {
|
||||||
store *store.Store
|
store *store.Store
|
||||||
cache *cache.Cache
|
cache *cache.Cache
|
||||||
@@ -51,8 +45,11 @@ func (r *Router) Route(ctx context.Context, rule *model.Rule, title, content str
|
|||||||
if ch.Config != nil {
|
if ch.Config != nil {
|
||||||
cfg = *ch.Config
|
cfg = *ch.Config
|
||||||
}
|
}
|
||||||
if err := s.Send(title, content, cfg); err != nil {
|
r := retry.DefaultRetrier()
|
||||||
slog.Error("send failed", "channel_type", ch.Type, "channel_id", ch.ID, "error", err)
|
if err := r.Do(context.Background(), func() error {
|
||||||
|
return s.Send(title, content, cfg)
|
||||||
|
}); err != nil {
|
||||||
|
slog.Error("send failed after retries", "channel_type", ch.Type, "channel_id", ch.ID, "error", err)
|
||||||
} else {
|
} else {
|
||||||
slog.Info("sent", "channel_type", ch.Type, "channel_id", ch.ID)
|
slog.Info("sent", "channel_type", ch.Type, "channel_id", ch.ID)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
@@ -63,7 +64,11 @@ func (h *NotifyHandler) Handle(c *gin.Context) {
|
|||||||
// 4. Evaluate conditions
|
// 4. Evaluate conditions
|
||||||
if rule.Conditions != nil {
|
if rule.Conditions != nil {
|
||||||
var conds []model.Condition
|
var conds []model.Condition
|
||||||
if err := json.Unmarshal(*rule.Conditions, &conds); err == nil {
|
if err := json.Unmarshal(*rule.Conditions, &conds); err != nil {
|
||||||
|
slog.Error("failed to unmarshal rule conditions", "rule_id", rule.ID, "error", err)
|
||||||
|
c.JSON(http.StatusUnprocessableEntity, gin.H{"error": "invalid rule conditions"})
|
||||||
|
return
|
||||||
|
}
|
||||||
if !condition.Evaluate(conds, msg.Data) {
|
if !condition.Evaluate(conds, msg.Data) {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"matched": true,
|
"matched": true,
|
||||||
@@ -73,7 +78,6 @@ func (h *NotifyHandler) Handle(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 5. Get template content
|
// 5. Get template content
|
||||||
tmpl, err := h.store.GetTemplate(c.Request.Context(), rule.TemplateID)
|
tmpl, err := h.store.GetTemplate(c.Request.Context(), rule.TemplateID)
|
||||||
@@ -93,9 +97,10 @@ func (h *NotifyHandler) Handle(c *gin.Context) {
|
|||||||
title := src.Name + ": " + msg.Event
|
title := src.Name + ": " + msg.Event
|
||||||
channels := h.router.Route(c.Request.Context(), rule, title, content)
|
channels := h.router.Route(c.Request.Context(), rule, title, content)
|
||||||
|
|
||||||
// 8. Log message (best effort)
|
// 8. Log message (best effort, detached context)
|
||||||
go func() {
|
go func() {
|
||||||
payloadJSON, _ := json.Marshal(msg.Data)
|
payloadJSON, _ := json.Marshal(msg.Data)
|
||||||
|
ctx := context.Background()
|
||||||
for _, chName := range channels {
|
for _, chName := range channels {
|
||||||
chID := parseChannelID(chName)
|
chID := parseChannelID(chName)
|
||||||
ml := &model.MessageLog{
|
ml := &model.MessageLog{
|
||||||
@@ -107,7 +112,9 @@ func (h *NotifyHandler) Handle(c *gin.Context) {
|
|||||||
Content: content,
|
Content: content,
|
||||||
Status: "pending",
|
Status: "pending",
|
||||||
}
|
}
|
||||||
_ = h.store.CreateMessageLog(c.Request.Context(), ml)
|
if err := h.store.CreateMessageLog(ctx, ml); err != nil {
|
||||||
|
slog.Warn("failed to create message log", "error", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user