Кратко

  • Порядковый номер IMAP — это текущее место письма. После окончательного удаления более раннего письма последующие номера сдвигаются. UID сохраняется между сеансами, но действует лишь внутри одного ящика и одной генерации UIDVALIDITY.
  • Смена UIDVALIDITY отзывает утверждение о непрерывности. Клиент обязан удалить соответствующий кеш и операции со старыми UID, чтобы совпавшее число не перенесло действие пользователя на другое письмо.

Команда осталась правильной, адресат команды сменился

Ноутбук сохранил входящие перед поездкой без связи. В его кеше UID 4821 означает счёт, который пользователь решил удалить. Пока ноутбук был отключён, оператор восстановил ящик в другом хранилище. Письма сохранились, прежняя таблица UID — нет. В новой нумерации 4821 получило другое сообщение.

При подключении всё выглядит штатно: подлинная учётная запись, защищённый канал, корректная команда. Если сервер оставит прежний UIDVALIDITY, случайное совпадение числа будет выдано за продолжение идентичности. Законное удаление попадёт в цель, которую пользователь не выбирал.

IMAP предпочитает потерять локальное состояние. Сервер объявляет новую генерацию, клиент отказывается от отложенной команды, очищает кеш этого ящика и синхронизируется заново.

Номер места удобен до первого сдвига

Порядковые номера описывают относительное положение в выбранном ящике. При двадцати письмах это числа от 1 до 20. Ими удобно запрашивать диапазоны и считать новые поступления.

Если письмо 6 expunge-операцией удалено окончательно, прежнее 7 становится 6, а все последующие сдвигаются. Одно число может последовательно обозначать разные сообщения. RFC 2060 закрепил это в IMAP4rev1; RFC 9051 сохраняет правило в IMAP4rev2.

Подключённый клиент получает уведомления и исправляет карту. Отключённое устройство не видит действий веб-клиента, другого телефона или серверного правила. После возвращения «письмо 6» — координата сегодняшнего списка, а не доказательство вчерашнего объекта.

В 1994 году IMAP4 отделил память от порядка

RFC 1730, опубликованный в декабре 1994 года, описал IMAP4 для удалённых почтовых ящиков и последующей синхронизации отключённых клиентов. UID — 32-битное число, строго возрастающее внутри ящика, допускающее пропуски и сохраняющееся между сеансами.

Клиент получил возможность связывать прочитанность и отложенные действия с письмом, не сравнивая каждый раз все тела. Но постоянство номера требует поддержки настоящего хранилища. Старые почтовые системы могли не иметь поля для UID; внешняя программа могла переупорядочить файлы; удалённый ящик мог появиться снова под тем же именем; восстановление могло вернуть содержимое без метаданных идентичности.

Стандарт не потребовал невозможной вечности и не разрешил скрытую перераздачу. Он сделал разрыв заметным.

UIDVALIDITY обозначает поколение, а не сам ящик

Каждый ящик сообщает UIDVALIDITY. Если старые UID больше не сохраняются, новое значение должно быть выше прежнего. Время создания и монотонный счётчик — допустимые способы реализации, но смысл не зависит от единственного алгоритма. Клиент должен отличить новую генерацию от той, которую помнит.

RFC 2683 исправляет распространённую ошибку: UIDVALIDITY не является ID почтового ящика. Два ящика могут иметь одинаковое значение, а UID уникален только в своём ящике. Пары UIDVALIDITY и UID недостаточно для глобального 64-битного идентификатора. Нужен ещё контекст имени ящика.

RFC 3501, а затем RFC 9051 требуют, чтобы тройка имя–UIDVALIDITY–UID всегда относилась к одному неизменяемому сообщению на сервере. Тело, конверт, внутренняя дата, размер и структура не могут под той же тройкой стать другим содержимым. Флаги изменяемы по назначению. После expunge UID нельзя выдать заново в той же генерации.

Уникальность обеспечивается не внушительным числом, а областью действия, запретом повторного использования и явным окончанием гарантии.

Несовершенное хранилище должно признать ограничение

Смена UIDVALIDITY заставляет клиентов перестраивать кеш, поэтому спецификации настойчиво рекомендуют сохранять UID. И всё же RFC 4315 вводит UIDNOTSTICKY для старых хранилищ без постоянных UID, одновременно советуя не проектировать так новые системы.

Исключение не прячется. Если сервер не держит обещание, он должен сказать об этом. RFC 2683 называет худшее последствие игнорирования смены: клиент удалит не то письмо по устаревшему UID. Столь же ошибочно могут сработать перенос, копирование, установка флага или загрузка.

Чем точнее автоматика воспроизводит действия, сделанные офлайн, тем строже должна быть проверка генерации.

Очистка кеша отзывает полномочия старого намерения

RFC 4549 задаёт порядок синхронизации отключённого клиента. Открывая ящик, он сравнивает полученный UIDVALIDITY с сохранённым. При несовпадении клиент обязан опустошить кеш этого ящика, удалить операции со старыми UID и считать их неудавшимися.

Похожая тема, дата или длина не возвращают прежней команде адресата. Это признаки для поиска, а не основание переносить удаление на найденный объект. С новой генерацией полномочия теряют и кешированные данные, и связанные с ними решения пользователя.

Область сброса локальна. RFC 2683 не рекомендует единый серверный пул UID: он быстрее расходует 32 бита и способен распространить одно исчерпание на все ящики. Локальный диапазон ограничивает радиус отказа.

Сохранённой ссылке тоже нужен тест на устаревание

RFC 2192 в 1997 году разрешил включать в IMAP URL имя ящика, UIDVALIDITY и UID. Открывающая программа должна сравнить сохранённую генерацию с текущей и распознать устаревшую ссылку.

UIDVALIDITY — не срок годности письма, не подтверждение автора, доступа или криптографической целостности. Это свидетельство того, остаётся ли ссылка в пространстве идентичности, где ей первоначально придали смысл.

Хорошая долговременная ссылка несёт не только адрес, но и условие, после которого она должна перестать утверждать, что нашла тот же объект.

Быстрая синхронизация всё равно начиналась с поколения

Большие ящики и мобильные обрывы сделали полную сверку дорогой. RFC 7162 объединил CONDSTORE и QRESYNC: последовательности изменений помогают получить новые флаги, VANISHED компактно сообщает удалённые UID, а восстановление состояния возможно за один обмен.

Первый параметр состояния QRESYNC — последний известный UIDVALIDITY. Если он не совпадает, сервер игнорирует оставшуюся последовательность изменений и набор UID. Эти данные могут быть точны, но описывают другую генерацию объектов.

Сначала следует доказать, что сравниваются те же сущности, и только потом вычислять изменения. Скорость не исправляет ошибку идентичности.

UIDONLY убрал относительные номера, но не границу

В мае 2024 года Experimental RFC 9586 определил UIDONLY. После включения клиент не использует порядковые номера, а сервер не возвращает их. UID-команды и VANISHED заменяют карту между подвижными позициями и устойчивыми UID, сокращая расход ресурсов.

Документ не требует всеобщего внедрения и не измеряет его. Но направление показательно: через тридцать лет после IMAP4 работа всё ещё уходит от двусмысленных координат.

UIDONLY не делает UID всемирным или вечным. Число остаётся внутри ящика и UIDVALIDITY. Удаление позиции не отменяет поколения.

Идентификатор долговечен, потому что умеет честно закончиться

IMAP распределил ответственность по знанию. Сервер управляет хранилищем и объявляет, сохранилась ли непрерывность UID. Клиент управляет кешем и отложенными намерениями и отзывает их при смене поколения. Удобство ни для одной стороны не считается доказательством.

Общий слой остаётся тонким: он не диктует базу данных, способ миграции или формат локального кеша. Он определяет инвариант, сигнал разрыва и безопасную реакцию. Реализации могут различаться, но старое число не должно молча получить власть над новым письмом.

UID переживает сеансы именно потому, что UIDVALIDITY умеет объявить: перерождение ящика он не пережил.

Источники и ограничения

Проект 1994 года дан в RFC 1730; номера, UID и тройка идентичности — в RFC 2060, RFC 3501 и RFC 9051. RFC 2683 описывает опыт реализации, RFC 2192 ссылки, RFC 4315 UIDNOTSTICKY, RFC 4549 работу офлайн, RFC 7162 QRESYNC, RFC 9586 Experimental UIDONLY. Они не доказывают нынешнюю распространённость, поведение конкретного продукта, подлинность письма, криптографическую целостность или единственный способ формирования UIDVALIDITY.