Refactor Kafka publishing without DB outbox
This commit is contained in:
@@ -6,10 +6,57 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/segmentio/kafka-go"
|
||||
"github.com/tinode/chat/server/logs"
|
||||
"github.com/tinode/chat/server/store"
|
||||
"github.com/tinode/chat/server/store/types"
|
||||
)
|
||||
|
||||
func startKafkaDeadLetterConsumer() {
|
||||
startKafkaConsumer("dead_letter", handleKafkaDeadLetter)
|
||||
}
|
||||
|
||||
func handleKafkaDeadLetter(ctx context.Context, envelope kafkaEnvelope, _ kafka.Message) error {
|
||||
var dead types.KafkaDeadLetter
|
||||
if err := json.Unmarshal(envelope.Payload, &dead); err != nil {
|
||||
return err
|
||||
}
|
||||
if dead.DeadID == "" {
|
||||
dead.DeadID = envelope.EventID
|
||||
}
|
||||
tenantID, err := tenantIDFromDeadLetter(envelope, &dead)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
now := time.Now().UTC().Round(time.Millisecond)
|
||||
if err = store.HTTPInfrastructure.MarkKafkaConsumeDead(tenantID, &dead, now); err != nil {
|
||||
return err
|
||||
}
|
||||
if auditErr := enqueueKafkaAuditEvent(ctx, tenantID, "system", types.ZeroUid, "kafka.dead_letter.created", "kafka_event", dead.EventID, "dead", dead.LastReason, map[string]any{
|
||||
"dead_id": dead.DeadID,
|
||||
"event_type": dead.EventType,
|
||||
"biz_type": dead.BizType,
|
||||
"biz_id": dead.BizID,
|
||||
"consumer_group": dead.ConsumerGroup,
|
||||
}); auditErr != nil {
|
||||
logs.Warn.Printf("kafka dead letter audit enqueue failed: event=%s dead=%s err=%v", dead.EventID, dead.DeadID, auditErr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func tenantIDFromDeadLetter(envelope kafkaEnvelope, dead *types.KafkaDeadLetter) (types.TenantID, error) {
|
||||
if !envelope.TenantID.IsZero() {
|
||||
return envelope.TenantID, nil
|
||||
}
|
||||
if dead != nil && len(dead.Envelope) > 0 {
|
||||
var original kafkaEnvelope
|
||||
if err := json.Unmarshal(dead.Envelope, &original); err == nil && !original.TenantID.IsZero() {
|
||||
return original.TenantID, nil
|
||||
}
|
||||
}
|
||||
return kafkaTenantID(envelope.TenantCode)
|
||||
}
|
||||
|
||||
func replayKafkaDeadLetter(ctx context.Context, tenantID types.TenantID, deadID string, actor types.Uid, note string) (*types.KafkaDeadLetter, error) {
|
||||
now := time.Now().UTC().Round(time.Millisecond)
|
||||
dead, err := store.HTTPInfrastructure.MarkKafkaDeadLetterReplay(tenantID, deadID, actor.UserId(), note, now)
|
||||
|
||||
Reference in New Issue
Block a user