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:
@@ -1001,12 +1001,18 @@ internal class MessageStore : IDisposable
|
|||||||
// SQL narrows by Receiver + ChatType (indexed); client does the final
|
// SQL narrows by Receiver + ChatType (indexed); client does the final
|
||||||
// PlayerPayload comparison. sqlScanLimit caps the scan to stay within
|
// PlayerPayload comparison. sqlScanLimit caps the scan to stay within
|
||||||
// the message-processing worker thread budget.
|
// 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(
|
internal IReadOnlyList<Message> GetTellHistoryWithSender(
|
||||||
ulong receiver,
|
ulong receiver,
|
||||||
string senderName,
|
string senderName,
|
||||||
uint senderWorld,
|
uint senderWorld,
|
||||||
int limit,
|
int limit
|
||||||
int sqlScanLimit = 500
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (limit <= 0)
|
if (limit <= 0)
|
||||||
@@ -1024,14 +1030,12 @@ internal class MessageStore : IDisposable
|
|||||||
WHERE deleted = false
|
WHERE deleted = false
|
||||||
AND Receiver = $Receiver
|
AND Receiver = $Receiver
|
||||||
AND ChatType IN ($TellIncoming, $TellOutgoing)
|
AND ChatType IN ($TellIncoming, $TellOutgoing)
|
||||||
ORDER BY Date DESC
|
ORDER BY Date DESC;
|
||||||
LIMIT $ScanLimit;
|
|
||||||
";
|
";
|
||||||
cmd.CommandTimeout = 60;
|
cmd.CommandTimeout = 60;
|
||||||
cmd.Parameters.AddWithValue("$Receiver", receiver);
|
cmd.Parameters.AddWithValue("$Receiver", receiver);
|
||||||
cmd.Parameters.AddWithValue("$TellIncoming", (int)ChatType.TellIncoming);
|
cmd.Parameters.AddWithValue("$TellIncoming", (int)ChatType.TellIncoming);
|
||||||
cmd.Parameters.AddWithValue("$TellOutgoing", (int)ChatType.TellOutgoing);
|
cmd.Parameters.AddWithValue("$TellOutgoing", (int)ChatType.TellOutgoing);
|
||||||
cmd.Parameters.AddWithValue("$ScanLimit", sqlScanLimit);
|
|
||||||
|
|
||||||
var collected = new List<Message>();
|
var collected = new List<Message>();
|
||||||
using var enumerator = new MessageEnumerator(cmd.ExecuteReader(), _logger);
|
using var enumerator = new MessageEnumerator(cmd.ExecuteReader(), _logger);
|
||||||
|
|||||||
Reference in New Issue
Block a user