Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions blog/2021-11-03-hello.md

This file was deleted.

111 changes: 111 additions & 0 deletions blog/2026-11-10-v0.164.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
---
slug: v0.164.0
title: "gotd v0.164.0: built for long-running clients"
authors: [ernado]
tags: [release]
---

gotd v0.164.0 and gotd/contrib v0.26.0 are about clients that run for weeks: archivers,
userbots and services with many accounts in one process. Most changes came from running
gotd in such an archiver. They close gaps where gotd went quiet, waited forever or lost
data, and add the metrics needed to see that it works.

{/* truncate */}

## Highlights

### Know when something is wrong

- **Lost authorization.** `OnAuthLost` is called once when an authorized session is
terminated (`AUTH_KEY_UNREGISTERED`, `SESSION_REVOKED` and similar). Return an error to
stop `Run` with `*telegram.AuthLostError`, so one account can be stopped and reported
while others keep running.
- **Connection events with a DC.** `OnConnectionStateEvent` and `OnConnDead` say which
DC and which kind of connection (primary, data, CDN) an event is about.
- **Stuck requests.** `RequestTimeout` sets a per-request deadline. When it passes, the
client reconnects and resends the request once, like Telegram Desktop. New
`PingInterval` and `PingTimeout` options control liveness checks.
- **Metrics and logs.** Pass a `MeterProvider` to the client and the updates manager for
OpenTelemetry metrics of connections, requests, pools, update recovery and downloads,
with debug logs at each event. Nothing is recorded unless you set it. See
[Observability](/docs/advanced/observability).

### Updates that don't go missing

- Messages returned with `channelDifferenceTooLong` were dropped. They are now passed to
`OnChannelGap` together with the gap range. They're not sent to the handler, since they
may include messages it already received.
- `Manager.TrackChannel` tracks channels joined while offline, and channels reported by
`OnLoadChannelStateFailed`.
- `BeforeRun` decides what happens to updates that arrive before the manager starts:
pass them, buffer them, or drop them for recovery to fetch again.
- `UpdateDispatcher` handlers registered on one copy are now seen by every copy, so
`OnFallback` is no longer lost when the dispatcher is passed by value. The new
`OnAny*` handlers cover private chats, groups and channels in one place, including
forum topics. The `OnBefore` hook sees every update.

### Downloads for archivers

- Resume with `WithOffset`, a known `WithSize` and `WithProgress`. `Builder.Verify`
checks a local file against the server's hashes.
- `WithRefresh` gets a fresh location when a file reference expires. The new `fileref`
package builds one from a message, a story or a profile photo.
- `Scheduler` is an adaptive window of part requests shared between downloads, like
Telegram Desktop's. It grows on success and halves on flood waits. Set
`Options.DownloadScheduler` to get one per DC.
- `Client.FileDC` gives a cached connection pool for a DC and follows `FILE_MIGRATE`.
`Client.DC` to the home DC no longer fails with `DC_ID_INVALID`. CDN downloads now
work through any invoker (`DownloadVia`).

### Queries

- `MinID`/`MaxID` on history iterators.
- Resumable cursors for messages and dialogs.
- `ForEachFolder` over all dialog folders.
- `GetMessagesWithEntities`.
- A new `query/stories` package.
- `DialogKey.InputPeer()`.
- `ExtractPeer` no longer builds unusable peers from min users. Min users and channels
are merged into full ones the way TDLib does it.

### Also

- QR login completes 2FA through `Options.Password`.
- Takeout sessions can be resumed with `takeout.NewClient` and handle
`TAKEOUT_INIT_DELAY`.
- `tg.EntitiesFrom(users, chats)`.

## gotd/contrib v0.26.0

- **Storage:** persistent updates state and access hashes for pebble, bbolt and redis.
pebble and bbolt also implement `peers.Storage` for `telegram/peers`.
- **Fewer writes:** pebble honours its write options and writes a whole update's peers
in one batch instead of one fsync per peer. Unchanged peers aren't rewritten.
- **Encoding:** a compact binary peer encoding, opt-in with `WithBinaryEncoding()`.
Versions before v0.26.0 can't read it, so turn it on only once you won't roll back.
- **Min users:** they no longer overwrite stored full users.
- **floodwait** gains:
- concurrent dispatch, so a slow request no longer blocks the others;
- adaptive pacing, policies, exempt methods and retries of 5xx errors;
- a snapshot for metrics.

## Upgrading

Most changes are additions. Check these:

- **`ExtractPeer`** returns `peer.ErrMinPeer` for min users and channels, where it used
to build an input peer from the min access hash. The iterators handle this. Check your
own callers.
- **After `Run` stops,** `updates.Manager.Handle` and `TrackChannel` return
`updates.ErrStopped` instead of blocking.
- **contrib storage:**
- `storage.Peer.FromUser` returns false for min users;
- `CreatedAt` now means "first stored with this content";
- pebble writes without sync if you passed `NoSync` write options, which used to be
ignored.
- **contrib floodwait** now runs requests concurrently; it used to send one per tick.

Thanks to everyone who reported issues in [@gotd_en](https://t.me/gotd_en) and
[@gotd_ru](https://t.me/gotd_ru). Full list of changes:
[gotd/td](https://github.com/gotd/td/releases/tag/v0.164.0),
[gotd/contrib](https://github.com/gotd/contrib/releases/tag/v0.26.0).
20 changes: 9 additions & 11 deletions docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,10 @@ const config = {
// Please change this to your repo.
editUrl: 'https://github.com/gotd/docs/edit/main/docs/',
},
// blog: {
// showReadingTime: true,
// // Please change this to your repo.
// editUrl:
// 'https://github.com/gotd/docs/edit/main/blog/',
// },
blog: {
showReadingTime: true,
editUrl: 'https://github.com/gotd/docs/edit/main/',
},
theme: {
customCss: require.resolve('./src/css/custom.css'),
},
Expand Down Expand Up @@ -83,7 +81,7 @@ const config = {
position: 'left',
label: 'API Reference',
},
// {to: '/blog', label: 'Blog', position: 'left'},
{to: '/blog', label: 'Blog', position: 'left'},
{
to: '/docs/support',
label: 'Support',
Expand Down Expand Up @@ -124,10 +122,10 @@ const config = {
{
title: 'More',
items: [
// {
// label: 'Blog',
// to: '/blog',
// },
{
label: 'Blog',
to: '/blog',
},
{
label: 'GitHub',
href: 'https://github.com/gotd/td',
Expand Down
Loading