v0.0.18.4 Фикс активного соединения
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
madipo2611 2025-08-17 08:32:32 +03:00
parent 903c8bb2ff
commit f9e9347389

View File

@ -3,6 +3,7 @@ package graph
import ( import (
"context" "context"
"fmt" "fmt"
"log"
"tailly_back_v2/internal/domain" "tailly_back_v2/internal/domain"
"tailly_back_v2/proto" "tailly_back_v2/proto"
"time" "time"
@ -120,25 +121,62 @@ func (r *queryResolver) GetUserChats(ctx context.Context, userID int) ([]*domain
// MessageStream реализация подписки на новые сообщения // MessageStream реализация подписки на новые сообщения
func (r *subscriptionResolver) MessageStream(ctx context.Context, userID int) (<-chan *domain.Message, error) { func (r *subscriptionResolver) MessageStream(ctx context.Context, userID int) (<-chan *domain.Message, error) {
messageChan := make(chan *domain.Message, 10) // Буферизованный канал
go func() {
defer close(messageChan)
retryCount := 0
maxRetries := 5
for {
if retryCount >= maxRetries {
log.Printf("Max retries (%d) reached for user %d", maxRetries, userID)
return
}
// Создаем новое соединение
stream, err := r.MessageClient.StreamMessages(ctx, &proto.StreamMessagesRequest{ stream, err := r.MessageClient.StreamMessages(ctx, &proto.StreamMessagesRequest{
UserId: int32(userID), UserId: int32(userID),
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to stream messages: %w", err) log.Printf("Stream connection error for user %d: %v (retry %d)", userID, err, retryCount)
retryCount++
select {
case <-ctx.Done():
return
case <-time.After(time.Duration(retryCount) * time.Second):
continue
}
} }
messageChan := make(chan *domain.Message) retryCount = 0 // Сброс счетчика при успешном подключении
go func() {
defer close(messageChan)
for { for {
msg, err := stream.Recv() msg, err := stream.Recv()
if err != nil { if err != nil {
return log.Printf("Stream receive error for user %d: %v", userID, err)
break
} }
// Пропускаем heartbeat сообщения
if msg.Message.GetContent() == "__heartbeat__" {
continue
}
select { select {
case <-ctx.Done(): case <-ctx.Done():
return return
case messageChan <- protoMessageToDomain(msg.Message): case messageChan <- protoMessageToDomain(msg.Message):
// Сообщение успешно отправлено в канал
}
}
// Пауза перед повторной попыткой
select {
case <-ctx.Done():
return
case <-time.After(1 * time.Second):
retryCount++
} }
} }
}() }()
@ -148,6 +186,9 @@ func (r *subscriptionResolver) MessageStream(ctx context.Context, userID int) (<
// Преобразование proto-сообщения в domain-модель // Преобразование proto-сообщения в domain-модель
func protoMessageToDomain(msg *proto.Message) *domain.Message { func protoMessageToDomain(msg *proto.Message) *domain.Message {
if msg == nil {
return nil
}
return &domain.Message{ return &domain.Message{
ID: int(msg.Id), ID: int(msg.Id),
ChatID: int(msg.ChatId), ChatID: int(msg.ChatId),