// 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 }