mirror of
https://github.com/tiennm99/telegram-exporter.git
synced 2026-10-04 04:13:33 +00:00
The walk collects every item's file reference up front, and Telegram expires those. The lifetime is undocumented; a run was seen to outlast an hour and fail before two, which is less than a large chat spends downloading. So every fetch past that point returned FILE_REFERENCE_EXPIRED, five in a row tripped the breaker, and the run abandoned the rest of its todo list. Telegram's contract is to cache a reference together with the source it came from and re-read that source when it expires, so each message is re-read for a live reference immediately before its own download. That is one round trip per transfer and needs no guess at how long a reference lives. It runs after the staging acquire rather than before: that acquire is the run's brake and blocks for as long as the destination is slow, which on a stalled remote is long enough to expire a fresh reference all over again. A re-read that describes a different file — different name or different length — is refused, because archiving it under the name this run recorded would store the wrong bytes. That case, a deleted message, and one that no longer holds a file are all skipped: nothing can be archived for them, and one must not strand the rest of the chat. Any other re-read failure is recorded as a failed download instead, because that is what it is. The connection that serves the re-read is the one that serves the file, so these arrive exactly when transfers are failing too. An item that never reaches a worker never reaches OnAdd or OnDone, so on the skip path it would move no counter, feed no streak and produce no outcome to retry — a source outage would walk the whole list one dead round trip at a time and still exit as merely incomplete. tutil.GetSingleMessage is not reused for the re-read: it reports a deleted message three different ways, two of them wrapping a nil error, and only one is distinguishable — so deletions would be misclassified as transient and spend the breaker's streak.