fix: add retry delay to prevent infinite loop in message history loading

BUG FIX: When opening chat, only the last message was visible instead of
full history (100 messages).

Root cause:
In get_chat_history(), when TDLib returns fewer messages than requested on
first attempt (e.g., 1 message instead of 50), the retry logic would
`continue` without updating from_message_id. This caused the SAME request
to be repeated 20 times, loading the same single message repeatedly.

Code flow (BEFORE fix):
1. Request: get_chat_history(from_message_id=0, limit=50)
2. TDLib returns: 1 message (still syncing with server)
3. Check: received_count < chunk_size? YES → continue
4. Request: get_chat_history(from_message_id=0, limit=50)  // SAME request!
5. Repeat 20 times...
6. Result: Only 1 message loaded

Fix:
Added `sleep(Duration::from_millis(100))` before retry to give TDLib time
to sync with server between attempts. This prevents infinite retry loop and
allows TDLib to actually load more messages.

Code flow (AFTER fix):
1. Request: get_chat_history(from_message_id=0, limit=50)
2. TDLib returns: 1 message
3. Check: received_count < chunk_size? YES → sleep 100ms + continue
4. Request: get_chat_history(from_message_id=0, limit=50)
5. TDLib returns: 50 messages (had time to sync)
6. Result: Full history loaded

Also added missing imports:
- use tokio::time::{sleep, Duration};

Impact: Critical - users couldn't see message history when opening chats.

Related commit: 72c4a88 (which removed the sleep but didn't account for retry)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Mikhail Kilin
2026-02-05 21:52:08 +03:00
parent 7dbb2209c8
commit 7823efa724

View File

@@ -3,6 +3,7 @@ use crate::types::{ChatId, MessageId};
use tdlib_rs::enums::{InputMessageContent, InputMessageReplyTo, SearchMessagesFilter, TextParseMode}; use tdlib_rs::enums::{InputMessageContent, InputMessageReplyTo, SearchMessagesFilter, TextParseMode};
use tdlib_rs::functions; use tdlib_rs::functions;
use tdlib_rs::types::{FormattedText, InputMessageReplyToMessage, InputMessageText, Message as TdMessage, TextParseModeMarkdown}; use tdlib_rs::types::{FormattedText, InputMessageReplyToMessage, InputMessageText, Message as TdMessage, TextParseModeMarkdown};
use tokio::time::{sleep, Duration};
use super::types::{MessageBuilder, MessageInfo, ReplyInfo}; use super::types::{MessageBuilder, MessageInfo, ReplyInfo};
@@ -188,9 +189,11 @@ impl MessageManager {
// Если это первая загрузка и получили мало сообщений - продолжаем попытки // Если это первая загрузка и получили мало сообщений - продолжаем попытки
// TDLib может подгружать данные с сервера постепенно // TDLib может подгружать данные с сервера постепенно
if all_messages.is_empty() && if all_messages.is_empty() &&
received_count < (chunk_size as usize) && received_count < (chunk_size as usize) &&
attempt < max_attempts_per_chunk { attempt < max_attempts_per_chunk {
// Даём TDLib время на синхронизацию с сервером
sleep(Duration::from_millis(100)).await;
continue; continue;
} }