bridge: MessageID=хэш(дедуп), классификация permanent/transient SQS-ошибок, бесконечный ретрай подписки, валидация ns/deviceID
This commit is contained in:
@@ -104,28 +104,29 @@ func connectMQTT(ctx context.Context, cfg *config.Config, log *slog.Logger, hand
|
||||
})
|
||||
opts.SetOnConnectHandler(func(c mqtt.Client) {
|
||||
log.Info("bridge: MQTT connected")
|
||||
// Подписка обязательна. Ретраим ограниченно. НЕ вызываем c.Disconnect():
|
||||
// в paho это ЯВНОЕ отключение, после которого автореконнект НЕ срабатывает
|
||||
// — bridge оставался бы отключённым навсегда (ревью 2026-10-10, 🔴6).
|
||||
// При сбое ждём следующего реконнекта (OnConnectHandler вызовется заново).
|
||||
for attempt := 1; attempt <= 3; attempt++ {
|
||||
// Подписка обязательна. Ретраим пока не удастся (или не оборвётся ctx/
|
||||
// соединение). НЕ вызываем c.Disconnect(): в paho это ЯВНОЕ отключение,
|
||||
// после которого автореконнект НЕ срабатывает (ревью 2026-10-10, 🔴6).
|
||||
// Раньше было 3 попытки и ожидание следующего реконнекта — но при живом
|
||||
// соединении OnConnectHandler больше не вызовется, и bridge оставался бы
|
||||
// без подписки навсегда (ревью 2026-10-11).
|
||||
for {
|
||||
if ctx.Err() != nil || !c.IsConnected() {
|
||||
return
|
||||
}
|
||||
token := c.Subscribe(telemetryTopicFilter, 1, handler)
|
||||
if token.WaitTimeout(10*time.Second) && token.Error() == nil {
|
||||
log.Info("bridge: subscribed", "filter", telemetryTopicFilter, "attempt", attempt)
|
||||
log.Info("bridge: subscribed", "filter", telemetryTopicFilter)
|
||||
setSubscribed(onSubscribed, true)
|
||||
return
|
||||
}
|
||||
log.Error("bridge: subscribe failed", "filter", telemetryTopicFilter, "attempt", attempt, "err", token.Error())
|
||||
log.Error("bridge: subscribe failed, retrying", "filter", telemetryTopicFilter, "err", token.Error())
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(subscribeRetryInterval):
|
||||
}
|
||||
}
|
||||
// Подписка не удалась — bridge не готов (/ready=503) до следующего
|
||||
// реконнекта.
|
||||
setSubscribed(onSubscribed, false)
|
||||
log.Error("bridge: subscribe failed after retries, will retry on next reconnect", "filter", telemetryTopicFilter)
|
||||
})
|
||||
|
||||
client := mqtt.NewClient(opts)
|
||||
|
||||
Reference in New Issue
Block a user