- Добавлен ResolveQueueURLWithRetry (10 попыток × 2с backoff): временная ошибка GetQueueUrl больше не роняет bridge/consumer без ретрая. - main.go: при ПОСТОЯННОЙ ошибке bridge/consumer процесс завершается с кодом ≠ 0 (fatal-флаг + cancel), чтобы платформа перезапустила контейнер — раньше процесс оставался жив, а /health отдавал 200.
66 lines
2.3 KiB
Go
66 lines
2.3 KiB
Go
// Package sqsclient — общий фабричный клиент shared-SQS для монолита.
|
|
//
|
|
// Используют: bridge (SendMessage), consumer (ReceiveMessage/DeleteMessage),
|
|
// admin-stats (GetQueueUrl/GetQueueAttributes).
|
|
package sqsclient
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/aws/aws-sdk-go-v2/aws"
|
|
"github.com/aws/aws-sdk-go-v2/credentials"
|
|
"github.com/aws/aws-sdk-go-v2/service/sqs"
|
|
|
|
"gitea.services.ngcloud.ru/Nail/IoT/internal/service/config"
|
|
)
|
|
|
|
// New создаёт SQS-клиент с переопределённым endpoint (self-hosted shared-sqs).
|
|
func New(cfg *config.Config) *sqs.Client {
|
|
return sqs.New(sqs.Options{
|
|
Region: cfg.SQSRegion,
|
|
Credentials: credentials.NewStaticCredentialsProvider(
|
|
cfg.SQSAccessKey, cfg.SQSSecretKey, "",
|
|
),
|
|
BaseEndpoint: aws.String(cfg.SQSEndpoint),
|
|
})
|
|
}
|
|
|
|
// ResolveQueueURL получает URL очереди по имени (один вызов при старте).
|
|
func ResolveQueueURL(ctx context.Context, client *sqs.Client, queueName string) (string, error) {
|
|
out, err := client.GetQueueUrl(ctx, &sqs.GetQueueUrlInput{
|
|
QueueName: aws.String(queueName),
|
|
})
|
|
if err != nil {
|
|
return "", fmt.Errorf("sqs: GetQueueUrl %q: %w", queueName, err)
|
|
}
|
|
return aws.ToString(out.QueueUrl), nil
|
|
}
|
|
|
|
// ResolveQueueURLWithRetry — ResolveQueueURL с ретраями на старте. Временная
|
|
// ошибка GetQueueUrl (SQS ещё поднимается, сетевой сбой) не должна фатально
|
|
// ронять bridge/consumer без ретрая (ревью 2026-10-10, 🔴5). После исчерпания
|
|
// попыток возвращает ошибку — вызывающий должен завершить процесс ≠ 0 (платформа
|
|
// перезапустит контейнер).
|
|
func ResolveQueueURLWithRetry(ctx context.Context, client *sqs.Client, queueName string) (string, error) {
|
|
const attempts = 10
|
|
const backoff = 2 * time.Second
|
|
var lastErr error
|
|
for attempt := 1; attempt <= attempts; attempt++ {
|
|
url, err := ResolveQueueURL(ctx, client, queueName)
|
|
if err == nil {
|
|
return url, nil
|
|
}
|
|
lastErr = err
|
|
if attempt < attempts {
|
|
select {
|
|
case <-ctx.Done():
|
|
return "", lastErr
|
|
case <-time.After(backoff):
|
|
}
|
|
}
|
|
}
|
|
return "", lastErr
|
|
}
|