UnigramDev/Unigram/develop • a0b0763 • 1 files, +37/-10 Close the unbounded growth item: _files is T

Telegram github commits and releases

Telegram github commits and releases

@tgappsupdates

Broadcast from the most important Telegram clients' repositories

4,538 subscribers
Open in Telegram
UnigramDev/Unigram/developa0b07631 files, +37/-10
Close the unbounded growth item: _files is TDLib's model

Fela's read is right, and the reason is sharper than "a TDLib issue". The
contract is id-to-instance identity: updateFile carries a file id and ParseFile
mutates the existing instance in place, so every binding already holding that
File sees the change. TDLib never retires a file id within a session and never
signals that one is finished with. Drop an entry and the next update for that id
mints a new instance while the UI holds the old one, and that thumbnail stops
updating for good. Eviction is only safe when nothing holds the entry, which
means weak references plus a sweep plus a dereference per update on the receive
thread — a lot of machinery for the size involved.

Which the item never stated. One entry is three objects and three strings, the
strings dominating at roughly 700-1000 bytes, and every photo contributes an id
per size variant. Ten thousand files is about 8MB and a hundred thousand about
80MB: real, but not the multi-GB growth being chased elsewhere.

The three download sets were in this item only because they sit next to each
other in the file. They are ours rather than TDLib's, and they are hundreds of
KB at the top end. All four are already dropped on an authorization change by
the earlier Clear() fix.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

UnigramDev/Unigram/develop404313f2 files, +50/-12
Retry a forum topic that failed to load for a transient reason

UpdateNewTopic returned on any non-ForumTopic response before removing the id
from _pendingNewTopics, and GetTopic only requests a topic it has not already
asked for. So one failed load hid a topic for the rest of the session: the
method returned null forever and nothing ever asked again.

Clearing the entry on every failure would have been the worse bug. The
suppression is load-bearing — a topic that genuinely does not exist would
otherwise be requested again on every enumeration of the list, one round trip
per scroll, forever. It is also the only thing currently keeping the bogus
int.MaxValue lookup in GetTopics from repeating.

So the retry is scoped to failures that repeating can fix: code 500 and above,
or below zero, meaning server or transport. Every 4xx stays suppressed, since it
says the request is wrong or the topic is gone. Keying on 404 alone would not
have been enough, because TDLib reports a missing object as 400 at least as
often, which would have left the storm open through the more common code.

UpdateNewTopic now takes the id it asked for, a failure response carrying none
of its own. The call site inside UpdateDeleteMessages names its lambda parameter
inner, the enclosing callback having already bound response.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

#unigram
Open post in Telegram