Дельта media-objects перенесена в основную спеку: копирование больше не переносит отредактированную версию, копия показывается в исходном виде и не наследует параметры правок. Change перемещён в архив за 2026-10-21.
161 lines
11 KiB
Markdown
161 lines
11 KiB
Markdown
# media-objects Specification
|
||
|
||
## Purpose
|
||
|
||
Физическое объектное хранилище с непрозрачными ключами и журналом объектов:
|
||
привязка объектов к фото по ролям, совместное использование объектов несколькими
|
||
фото и сборка мусора по отсутствию ссылок.
|
||
|
||
## Requirements
|
||
|
||
### Requirement: Непрозрачные ключи хранилища
|
||
Слой хранения SHALL адресоваться непрозрачными ключами объектов, не содержащими
|
||
идентификаторов сущностей метаданных (таких как альбом или фото); сопоставление
|
||
ключей и сущностей SHALL храниться только в слое метаданных.
|
||
|
||
#### Scenario: Ключ без альбома
|
||
- **WHEN** система сохраняет объект в хранилище
|
||
- **THEN** ключ объекта не содержит идентификатора альбома
|
||
|
||
#### Scenario: Перенос не трогает ключи
|
||
- **WHEN** фото переносится в другой альбом
|
||
- **THEN** ключи его объектов остаются неизменными
|
||
|
||
### Requirement: Журнал объектов
|
||
|
||
Каждый физический объект SHALL иметь ровно одну запись в слое метаданных с ключом,
|
||
MIME-типом, размером, габаритами и состоянием; фото SHALL ссылаться на объекты по
|
||
ролям original, thumb, medium, preview, playback, edit, edit_thumb, edit_medium и
|
||
edit_preview.
|
||
|
||
#### Scenario: Привязка ролей
|
||
|
||
- **WHEN** фото загружено и обработано
|
||
- **THEN** фото ссылается на объект-оригинал и, когда они готовы, на объекты thumb, medium и preview
|
||
|
||
#### Scenario: Оригинал без вариантов
|
||
|
||
- **WHEN** варианты ещё не сгенерированы
|
||
- **THEN** фото доступно с оригиналом, а thumb, medium и preview отсутствуют
|
||
|
||
#### Scenario: Привязка роли воспроизведения
|
||
|
||
- **WHEN** видео обработано
|
||
- **THEN** медиа ссылается на объект playback наряду с оригиналом и постером
|
||
|
||
#### Scenario: Привязка отредактированной версии
|
||
|
||
- **WHEN** фото отредактировано и отредактированная версия отрендерена
|
||
- **THEN** фото ссылается на объекты edit, edit_thumb, edit_medium и edit_preview рядом с
|
||
исходными вариантами
|
||
|
||
### Requirement: Совместные объекты
|
||
Несколько фото SHALL иметь возможность ссылаться на один и тот же физический
|
||
объект; перенос и копирование SHALL изменять только ссылки и SHALL не изменять
|
||
объекты хранилища. Отредактированная версия SHALL создаваться и привязываться только
|
||
к тому фото, чьи правки её породили, в отличие от обычных вариантов, которые
|
||
разделяются копиями того же оригинала. Копирование SHALL NOT переносить
|
||
отредактированную версию на копию: копия фото с правками SHALL показываться в исходном
|
||
виде и SHALL NOT наследовать параметры правок.
|
||
|
||
#### Scenario: Копирование
|
||
- **WHEN** пользователь копирует фото в другой альбом
|
||
- **THEN** создаётся новая запись, ссылающаяся на те же объекты, без операций с хранилищем
|
||
|
||
#### Scenario: Перенос
|
||
- **WHEN** пользователь переносит фото в другой альбом
|
||
- **THEN** изменяется только привязка к альбому, объекты хранилища не меняются
|
||
|
||
#### Scenario: Правка не распространяется на копии
|
||
- **WHEN** фото скопировали в другой альбом, а затем отредактировали исходное фото
|
||
- **THEN** отредактированные объекты привязаны только к отредактированному фото, а копия
|
||
остаётся в исходном виде
|
||
|
||
#### Scenario: Копия отредактированного фото
|
||
- **WHEN** фото с уже отрендеренной отредактированной версией копируют в другой альбом
|
||
- **THEN** копия не получает отредактированные объекты, показывается в исходном виде и
|
||
не наследует параметры правок
|
||
|
||
### Requirement: Сборка мусора по ссылкам
|
||
Объект хранилища SHALL удаляться только когда на него не ссылается ни одно фото и ни один
|
||
аватар пользователя; удаление альбома и попадание фото в корзину SHALL сохранять объекты.
|
||
|
||
#### Scenario: Последняя ссылка удалена
|
||
- **WHEN** фото удаляется навсегда и больше ни одно фото не ссылается на его объекты
|
||
- **THEN** объекты удаляются из хранилища
|
||
|
||
#### Scenario: Остались ссылки
|
||
- **WHEN** на объект ссылается другое фото
|
||
- **THEN** объект сохраняется в хранилище
|
||
|
||
#### Scenario: Удаление альбома
|
||
- **WHEN** владелец удаляет альбом
|
||
- **THEN** объекты хранилища не удаляются
|
||
|
||
#### Scenario: Ссылка аватара
|
||
- **WHEN** на объект ссылается аватар пользователя
|
||
- **THEN** объект сохраняется в хранилище, пока ссылка существует
|
||
|
||
### Requirement: Устойчивость жизненного цикла объекта
|
||
Объект SHALL иметь состояние жизненного цикла, и незавершённые операции SHALL
|
||
самовосстанавливаться: неудачная загрузка не оставляет осиротевших объектов, а
|
||
удаление объекта SHALL доводиться до конца после сбоя.
|
||
|
||
#### Scenario: Сбой загрузки
|
||
- **WHEN** запись объекта создана, но загрузка в хранилище не завершилась
|
||
- **THEN** объект очищается без ручного вмешательства
|
||
|
||
#### Scenario: Сбой удаления
|
||
- **WHEN** удаление объекта из хранилища не удалось
|
||
- **THEN** попытка повторяется до успешного удаления
|
||
|
||
### Requirement: Генерация вариантов
|
||
Генерация вариантов SHALL выполняться через надёжную очередь заданий с
|
||
однократным выполнением и повтором при сбое; готовый результат SHALL
|
||
транслироваться подписчикам альбома. Очередь SHALL поддерживать настраиваемую
|
||
пропускную способность, SHALL обрабатывать более свежие фото раньше остальных и
|
||
SHALL различать короткие задания изображений и длительные задания видео. Рендер
|
||
отредактированных версий SHALL использовать отдельную очередь, чтобы правки не
|
||
блокировали генерацию обычных вариантов.
|
||
|
||
#### Scenario: Повтор после рестарта
|
||
- **WHEN** процесс перезапускается с незавершёнными заданиями
|
||
- **THEN** генерация вариантов продолжается
|
||
|
||
#### Scenario: Событие после генерации
|
||
- **WHEN** варианты фото готовы
|
||
- **THEN** подписчикам альбома публикуется событие обновления этого фото
|
||
|
||
#### Scenario: Приоритет свежих фото
|
||
- **WHEN** в очереди есть готовые к обработке задания разного возраста
|
||
- **THEN** система обрабатывает более свежие фото раньше
|
||
|
||
#### Scenario: Настраиваемая пропускная способность
|
||
- **WHEN** задан уровень параллелизма генерации
|
||
- **THEN** система обрабатывает варианты с этим уровнем параллелизма
|
||
|
||
#### Scenario: Длительное задание видео
|
||
- **WHEN** выполняется длительная подготовка видео
|
||
- **THEN** задание удерживается на весь срок выполнения и не вытесняет генерацию вариантов изображений
|
||
|
||
#### Scenario: Рендер правок не блокирует варианты
|
||
- **WHEN** в фоне выполняется рендер отредактированной версии
|
||
- **THEN** генерация обычных вариантов продолжается независимо от него
|
||
|
||
### Requirement: Аватар пользователя как объект журнала
|
||
Аватар пользователя SHALL храниться как объект журнала, привязанный к пользователю по ролям,
|
||
соответствующим нарезкам аватара. Замена и удаление аватара SHALL менять привязку, а объекты
|
||
без ссылок SHALL освобождаться сборкой мусора.
|
||
|
||
#### Scenario: Привязка аватара
|
||
- **WHEN** пользователь устанавливает аватар
|
||
- **THEN** объекты нарезок привязываются к пользователю по своим ролям
|
||
|
||
#### Scenario: Замена аватара
|
||
- **WHEN** пользователь заменяет аватар
|
||
- **THEN** привязка указывает на новые объекты, а старые освобождаются сборкой мусора
|
||
|
||
#### Scenario: Удаление аватара
|
||
- **WHEN** пользователь удаляет аватар
|
||
- **THEN** привязка снимается, и объекты аватара освобождаются сборкой мусора
|