fix(batch): SendMessageBatch пишет в Redis синхронно (как SendMessage) + не персистит дубли; SaveMessagesSync
This commit is contained in:
@@ -314,6 +314,37 @@ func SaveMessages(queueKey string, msgs []models.SqsMessage) {
|
||||
})
|
||||
}
|
||||
|
||||
// SaveMessagesSync — сохраняет несколько сообщений в Redis СИНХРОННО (pipeline).
|
||||
// Используется на пути SendMessageBatch: ответ 200 выдаётся только после записи
|
||||
// всех сообщений (как в одиночном SendMessage). Возвращает ошибку для отката.
|
||||
func SaveMessagesSync(queueKey string, msgs []models.SqsMessage) error {
|
||||
if Client == nil || len(msgs) == 0 {
|
||||
return nil
|
||||
}
|
||||
fields := make(map[string]string, len(msgs))
|
||||
for i := range msgs {
|
||||
data, err := json.Marshal(&msgs[i])
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshal message %s/%s: %w", queueKey, msgs[i].Uuid, err)
|
||||
}
|
||||
fields[msgs[i].Uuid] = string(data)
|
||||
}
|
||||
if len(fields) == 0 {
|
||||
return nil
|
||||
}
|
||||
hashKey := redisMsgHashPrefix + queueKey
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
args := make([]interface{}, 0, len(fields)*2)
|
||||
for k, v := range fields {
|
||||
args = append(args, k, v)
|
||||
}
|
||||
if err := Client.HSet(ctx, hashKey, args...).Err(); err != nil {
|
||||
return fmt.Errorf("HSet messages %s (%d msgs): %w", queueKey, len(fields), err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteMessagePersist — удаляет одно сообщение из Redis СИНХРОННО.
|
||||
// Синхронность обязательна: если удаление потеряется при рестарте пода,
|
||||
// сообщение «воскреснет» из Redis (факт: удалённые очереди возвращались
|
||||
|
||||
Reference in New Issue
Block a user