Design · 2026-05-28 · 8 min read8 мин чтения

A cursor-based model for media sessionsКурсорная модель медиа-сессий

The naive way to model a session is a mutable record the client re-reads on every poll. It works until two clients edit it, or the network drops a response and the client can't tell what it missed.

We model a session as an append-only event log with a monotonic offset. The client remembers the last offset it saw and asks: "what happened after N?" The server returns only those events.

GET /api/v4/media/session/state?offset=12
{ "offset": 14, "state": "playing",
  "events": [ {"offset":13,"type":"seek"}, {"offset":14,"type":"bitrate.up"} ] }

Why a cursor wins

  • Idempotent retries. A lost response just means the next poll re-fetches from the same offset.
  • No diffing. The server never compares snapshots; it slices a list.
  • Cheap multi-device. Each device keeps its own cursor over one shared log.

Trimming

Logs can't grow forever. We keep a bounded window per session and advance a low-water mark; clients that fall too far behind simply re-create. In practice players poll often enough that this never fires.

Наивный способ смоделировать сессию — изменяемая запись, которую клиент перечитывает на каждом поле. Работает, пока её не правят два клиента или пока сеть не теряет ответ — и клиент не знает, что пропустил.

Мы моделируем сессию как append-only лог событий с монотонным offset. Клиент помнит последний виденный offset и спрашивает: «что произошло после N?» Сервер отдаёт только эти события.

GET /api/v4/media/session/state?offset=12
{ "offset": 14, "state": "playing",
  "events": [ {"offset":13,"type":"seek"}, {"offset":14,"type":"bitrate.up"} ] }

Почему курсор выигрывает

  • Идемпотентные ретраи. Потерянный ответ — это просто перезапрос с того же offset.
  • Без диффов. Сервер не сравнивает снапшоты, он режет список.
  • Дёшево для мультидевайса. Каждое устройство держит свой курсор над одним логом.

Подрезка

Логи не могут расти вечно. Мы держим ограниченное окно на сессию и двигаем нижнюю границу; клиенты, отставшие слишком сильно, просто пересоздают сессию. На практике плееры поллят достаточно часто, чтобы это не срабатывало.

Back to blogНазад в блог