fix(autotells): preload tell history fully up to the user-configured limit

PreloadHistory had a hardcoded 500-row SQL scan window that capped the
per-partner history pull regardless of the AutoTellTabsHistoryPreload
setting. For active users with many tell partners, the scan window
filled up with chatter from other partners and pushed less-frequent
partners' history off the back end — pinned tabs reloaded empty even
though the messages were still in the database.

Drops the hardcoded scan cap. The (Receiver, Date) index keeps SQL fast
on the now-unbounded read, and the client-side loop still breaks as
soon as the configured per-tab limit is hit, so decode cost stays
proportional to the depth at which `limit` matches accumulate (typically
shallow even for chatty users).
This commit is contained in:
2026-05-16 12:16:08 +02:00
parent 679b8f0f5e
commit f66316161b
+9 -5
View File
@@ -1001,12 +1001,18 @@ internal class MessageStore : IDisposable
// SQL narrows by Receiver + ChatType (indexed); client does the final
// PlayerPayload comparison. sqlScanLimit caps the scan to stay within
// the message-processing worker thread budget.
// Walks the full receiver-filtered tell history newest-first and stops
// as soon as the per-partner match count reaches `limit`. The previous
// hardcoded 500-row scan window cut active users' less-frequent pinned
// partners out of the result whenever other partners' chatter pushed
// them off the back of the window. Index on (Receiver, Date) keeps the
// SQL side cheap; the client-side break bounds the actual decode cost
// to roughly the depth at which `limit` partner matches accumulate.
internal IReadOnlyList<Message> GetTellHistoryWithSender(
ulong receiver,
string senderName,
uint senderWorld,
int limit,
int sqlScanLimit = 500
int limit
)
{
if (limit <= 0)
@@ -1024,14 +1030,12 @@ internal class MessageStore : IDisposable
WHERE deleted = false
AND Receiver = $Receiver
AND ChatType IN ($TellIncoming, $TellOutgoing)
ORDER BY Date DESC
LIMIT $ScanLimit;
ORDER BY Date DESC;
";
cmd.CommandTimeout = 60;
cmd.Parameters.AddWithValue("$Receiver", receiver);
cmd.Parameters.AddWithValue("$TellIncoming", (int)ChatType.TellIncoming);
cmd.Parameters.AddWithValue("$TellOutgoing", (int)ChatType.TellOutgoing);
cmd.Parameters.AddWithValue("$ScanLimit", sqlScanLimit);
var collected = new List<Message>();
using var enumerator = new MessageEnumerator(cmd.ExecuteReader(), _logger);