fix: review findings (async SQS dispatcher, backoff, batch insert, shutdown order, pagination, HMAC) + loadtest fixes; v0.1.6

This commit is contained in:
“Naeel”
2026-08-16 18:24:09 +04:00
parent 090cedca67
commit 3fedf9317c
27 changed files with 581 additions and 122 deletions
+10 -25
View File
@@ -1,15 +1,15 @@
// handler.go — обработчик MQTT-сообщений: envelope → SQS SendMessage.
// handler.go — обработчик MQTT-сообщений: envelope → канал диспатчера SQS.
//
// Колбэк НЕ делает сетевых вызовов: только парсинг топика и неблокирующий
// enqueue. Отправка в SQS — worker-пул sqsDispatcher (см. sender.go).
package bridge
import (
"context"
"encoding/json"
"log/slog"
"strings"
"time"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/sqs"
mqtt "github.com/eclipse/paho.mqtt.golang"
)
@@ -22,15 +22,16 @@ type TelemetryEnvelope struct {
ReceivedAt string `json:"received_at"`
}
// newMessageHandler возвращает обработчик MQTT-сообщений.
func newMessageHandler(ctx context.Context, sqsClient *sqs.Client, queueURL string, log *slog.Logger) mqtt.MessageHandler {
// newMessageHandler возвращает обработчик MQTT-сообщений:
// валидация топика "{namespace}/telemetry/{deviceId}" → enqueue в диспатчер.
func newMessageHandler(dispatcher *sqsDispatcher, log *slog.Logger) mqtt.MessageHandler {
return func(_ mqtt.Client, msg mqtt.Message) {
topic := msg.Topic()
payload := msg.Payload()
// Топик: "{namespace}/telemetry/{deviceId}".
// Топик: "{namespace}/telemetry/{deviceId}". Пустые части — мусор.
parts := strings.SplitN(topic, "/", 3)
if len(parts) != 3 {
if len(parts) != 3 || parts[0] == "" || parts[2] == "" || parts[1] != "telemetry" {
log.Warn("bridge: unexpected topic format, skipping", "topic", topic)
return
}
@@ -44,28 +45,12 @@ func newMessageHandler(ctx context.Context, sqsClient *sqs.Client, queueURL stri
rawPayload = json.RawMessage(quoted)
}
envelope := TelemetryEnvelope{
dispatcher.enqueue(TelemetryEnvelope{
Namespace: ns,
DeviceID: deviceID,
Topic: topic,
Payload: rawPayload,
ReceivedAt: time.Now().UTC().Format(time.RFC3339),
}
body, err := json.Marshal(envelope)
if err != nil {
log.Error("bridge: marshal envelope", "topic", topic, "err", err)
return
}
_, err = sqsClient.SendMessage(ctx, &sqs.SendMessageInput{
QueueUrl: aws.String(queueURL),
MessageBody: aws.String(string(body)),
})
if err != nil {
log.Error("bridge: SQS SendMessage failed", "topic", topic, "err", err)
return
}
log.Info("bridge: forwarded telemetry to SQS",
"mqtt_topic", topic, "namespace", ns, "device", deviceID)
}
}