Кратко

  • RFC 3018 описал распределённую 128-битную память и инструкции удалённого чтения, записи, выделения, освобождения, работы с объектами и передачи управления.
  • Транзакция должна была исполнить весь набор сразу либо не исполнять ничего. Однако отмена после исполнения не предусматривалась, а передача управления прямо приводилась как действие, которое может быть невозможно отменить.

До запуска транзакция была сохранённым объектом. Получатель уже располагал всеми командами, но ещё не менял состояние. В этот момент EXEC_TR мог выпустить набор, а CANCEL_TR — удалить его.

После запуска объект превращался в события. Память могла быть записана или освобождена. Код мог начать работу. На другом узле мог появиться новый поток управления.

RFC 3018 не подменял эти состояния одним словом. В нём сказано, что отмена транзакции после выполнения не предусмотрена. Если нужна компенсация, её должна реализовать виртуальная машина, потому что некоторые команды—например, передача управления—могут не допускать отмены.

Документ Unified Memory Space Protocol Specification вышел в декабре 2000 года со статусом Experimental. Его замысел был шире обычного сетевого вызова. Приложение должно было видеть 128-битное пространство памяти, распределённое по Internet-узлам. VM преобразовывала обращение к удалённому адресу в команды UMSP: чтение, запись, сравнение, выделение или освобождение памяти, перенос кода, вызов объектной процедуры, JUMP или CALL.

Сеть исчезала из интерфейса программы. Из причин отказа она не исчезала.

Единый адрес не создавал единого хранителя

Вычисление делилось на job, task и thread of control. Job соответствовал распределённому приложению. На каждом узле у него была одна task, внутри которой могли работать несколько потоков. Job Control Point, JCP, координировал задачи и назначал идентификаторы.

Но JCP не владел всем состоянием. Локальная память, указатели, ресурсы и порядок исполнения оставались у VM. Протокол не контролировал память job и не отслеживал пользовательские потоки. После завершения task именно VM должна была сделать связанные с ней указатели недействительными.

Шестнадцатиоктетный адрес соединял сведения о сети, узле и локальной памяти. Он унифицировал имя, но не часы, журнал и полномочия восстановления. Переход на удалённый адрес создавал на целевом узле новый поток, хотя непрерывный участок кода нельзя было распределить по нескольким узлам.

Особенно важен этот разрыв для сильных команд. UMSP включал WRITE, MEM_ALLOC, FREE, перенос и запуск кода, JUMP, CALL, создание и удаление объектов, исполнение их процедур. Ошибка могла не просто испортить сообщение, а изменить удалённый ресурс или контрольный поток.

Полная доставка, ожидание и запуск были разными фактами

Протокол определял несколько типов chain. Sequence связывала зависимые команды: при неудаче текущей последующие отменялись. Transaction могла объединять несвязанные команды, но требовала исполнить их все одновременно либо не исполнять ни одну.

Длина была известна заранее из-за buffering. _BEGIN_TR открывал набор, _END_CHAIN отмечал последнюю команду. Только после этого у получателя появлялась полная транзакция.

При TRR=1 конец chain сразу запускал исполнение. При TRR=0 требовалась отдельная команда EXEC_TR. До запуска CANCEL_TR удаляла ранее переданные команды без возможности восстановления.

Флаг TRE придавал сбою сессии исполнительное значение. Полная, но ещё не исполненная транзакция с TRE=1 должна была запуститься по окончании срока жизни или при аварийном завершении сессии. При TRE=0 она отменялась. Отсчёт начинался лишь после получения всех команд, а ноль снимал ограничение.

Поэтому запись «соединение оборвалось» ничего не решает. Передача могла быть неполной. Набор мог полностью ждать. Он мог уже получить явное разрешение. Наконец, его могла запустить сама политика аварийного завершения.

Для расследования нужны раздельные квитанции: идентичность и ordered digest полной chain, состояние готового buffer, причина запуска или отмены и наблюдаемый результат каждой значимой команды.

Атомарность определяла вход, а не обратимость мира

Слово transaction легко наделить семантикой базы данных. RFC 3018 обещал более узкое свойство: команды входят в исполнение вместе или не входят вовсе.

После этого универсальной обратной команды может не существовать. Удалённую запись способен сразу прочесть другой поток. FREE может обесценить указатель, который хранится ещё где-то. Запущенный код может породить новые действия. Объектная процедура может изменить систему вне job. JUMP или CALL создают управление, способное пережить исходную chain.

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

Отмена относится к ещё ожидающему. Компенсация относится к уже возникшим последствиям и требует прикладного знания. Нельзя вывести безопасную компенсацию для любого эффекта только из opcode.

Поэтому EXEC_TR доказывает решение исполнить названную chain. Сам по себе он не доказывает завершение всех действий VM, однократность внешних эффектов или достижение цели приложения.

TCP подтверждал октеты, но не работу VM

UMSP требовал TCP для надёжного обмена и разрешал UDP для данных без подтверждения. RFC 793 задаёт надёжный упорядоченный поток октетов и обрабатывает потери, дубли, повреждения и перестановки. RFC 768 предоставляет минимальный datagram-сервис.

Эти свойства не превращаются автоматически в доказательство исполнения. TCP ACK говорит о приёме октетов на транспортном уровне. Он не говорит, что UMSP проверил команду, поместил её в правильную транзакцию, получил решение нужной стороны и исполнил на ожидаемой версии памяти.

RFC 1831 показывает соседнюю неопределённость ONC RPC. Полученный через TCP reply позволяет в описанной модели сделать вывод об исполнении. Отсутствие reply не позволяет заключить, что процедура не запускалась: server мог исполнить её до обрыва. Удалённый вызов отличается от локального отказами, побочными эффектами, производительностью и аутентификацией.

UMSP сделал удалённое действие ещё больше похожим на процессорную инструкцию. Удобство синтаксиса не отменяло распределённую природу свидетельств.

JCP координировал жизненный цикл, но не видел всё

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

При этом память и указатели контролировали VM. Удалённый поток мог породить внешний эффект, не наблюдаемый JCP напрямую. Соединение могло оборваться после действия и до ответа. После перезагрузки требовалось отличать сегменты старых сессий.

Завершение task — факт жизненного цикла. Сохранность записи — факт памяти. Однократность внешнего действия — факт приложения. Даже завершение job не объединяет эти свидетельства.

Безопасность сознательно оставили будущим расширениям

Security Considerations начинается с ограничения: вопросы безопасности не включены в минимальный механизм ради снижения первоначальной сложности. Дальнейшие пункты названы рекомендациями для развития.

Документ предлагает использовать защиту TCP/IP, специальные chain для контроля целостности или шифрования и параметры аутентификации в extension headers. Возможны комбинации аутентификации между двумя узлами и JCP. Защита от посредника связывается с непересекающимися маршрутами; общий gateway признаётся ослаблением.

JUMP и CALL также названы источниками denial-of-service, а управление ресурсами передано VM. Активный код от сервера опасен для клиента; исполнение клиентского кода требует усиления сервера.

Это перечень рисков, не законченная система. Не определены алгоритмы, ключи, авторизация, replay defense, отзыв и аудит.

Более поздний RFC 3552 рассматривает атакующего, способного читать, удалять, менять и внедрять сетевой трафик. Он не должен становиться ретроспективным требованием к документу 2000 года. Зато он показывает, почему разделённые маршруты и будущие заголовки нельзя считать готовой гарантией.

Experimental описывал разработку, а не эксплуатацию

RFC 2026 относит Experimental к документам вне standards track и говорит, что они не являются Internet Standards. Они могут сохранять исследования и разработки. RFC 2119 дал нормативные слова, RFC 2234 — ABNF.

Источники подтверждают проект UMSP, но не его внедрение, реализацию, interoperability, аварию или распространённость.

Исторический смысл документа — в честной границе сильной абстракции. Адресное пространство могло быть единым, а ответственность оставалась распределённой. Доставка могла завершиться, а решение о запуске ещё отсутствовать. Запуск мог быть атомарным, а последствия — необратимыми. Job мог закончиться, а внешний результат всё ещё требовал наблюдения.

Идеи Lu Heng используются здесь как явно названные аналитические линзы. Running-Code Primacy отделяет текст команды от результата работающего кода. Reality Layers разводит encoded chain, buffer, решение, исполнение и результат. Minimum Initial Specification объясняет пользу тонкого ядра, не разрешая домысливать отсутствующие контракты безопасности, компенсации и наблюдения.

Это не утверждения о намерениях автора RFC.

Протокол мог запустить пакет целиком. Целиком вернуть вызванную им реальность он не обещал.

Sources