Раздел 46 · Effect: Тихая Академия

Босс: две версии протокола

middle-senior~80 мин

без входаВойди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

Протокол, который живёт дольше года, обязательно получает вторую версию. Старую при этом не выключить в один день: на другом конце провода чужие башни, и у каждой свой график. Значит, надо уметь читать обе, а писать одну. Всё для этого уже есть в разделе: схемы с двумя сторонами из урока 79, цепочка Hop из урока 82, отказы словами из урока 81. Сегодня их надо сложить.

Что нужно башне

Тесты накопительные. Сверху новый модуль src/version.ts.

  • Две версии. Первая это кадр урока 79, StampedFrame, как есть: маршрут парой, ретранслятор отдельным полем. Вторая несёт поле version: 2 и вместо маршрута и ретранслятора цепочку path: Hop.
  • Миграция при разборе. Кадр первой версии, пройдя разбор, становится кадром второй. Цепочка откуда, куда, а если был ретранслятор, откуда, ретранслятор, куда. Остальные поля переезжают как есть, sentAt остаётся тем же моментом. Все проверки первой версии работают и при миграции: маршрут из одной башни дважды не пройдёт.
  • Наружу только v2. Входящая схема разбирает строку JSON любой версии и отдаёт FrameV2. Исходящая пишет только v2. Записать кадр первой версией Академия не может вовсе: такая запись запрещена в самой схеме.
  • Ночь. nightIntake(lines) разбирает ночь строк Магистрали. Ошибок в типе нет, мусор ночь не роняет. В отчёте принятые кадры в порядке строк, число пришедших первой версией и отказы вида строка N: беда; беда, все беды сразу, словами explain.
  • Отказ про ту версию, что прислали. Об этом ниже: это главная ловушка заказа.

Чек-лист перед сдачей

  1. Тесты всех прошлых этапов зелёные.
  2. Кадр v1 с ретранслятором даёт цепочку из трёх башен, без него из двух.
  3. Кадр v1 с маршрутом из одной башни дважды не проходит и после миграции.
  4. Исходящая и входящая схемы записывают один и тот же кадр v2.
  5. Битый кадр v2 получает отказ только про поля второй версии.
  6. Пустая ночь: { accepted: [], migrated: 0, rejected: [] }.

Магистраль, этап 9

Читать обе, писать одну

Подумай до кода, где в этом заказе схема работает за тебя, а где нужен твой выбор.

  • Миграция это преобразование. В уроке 79 строка провода превращалась в кадр и обратно. Здесь кадр v1 превращается в кадр v2. Это тот же Schema.decodeTo, только по обе стороны схемы кадров. Обратная сторона запрещена: в модуле SchemaGetter есть шаг, который на записи всегда отвечает бедой.
  • Миграция пишет на провод, а не в башню. Функция миграции получает уже разобранный кадр v1, с брендами и DateTime, а отдать должна то, что вторая версия ждёт на проводе: строки, ISO-время. Дальше вторая версия сама разберёт и проверит. Так проверки v2 не обойти даже своей миграцией.
  • Одна схема на вход. Строка с любой версией разбирается объединением двух договоров: v2 как есть или v1 с миграцией. Тип в башне у обоих вариантов один, FrameV2.

Почему не просто объединение

Объединение Union для ночи кажется готовым ответом: пусть Schema сама попробует обе версии. Попробуй на кадре v2, у которого битый код башни в цепочке:

[ 'path.tower: код башни вида T-число', 'route: нет поля' ]

Первая беда честная. Вторая ложная: у второй версии нет поля route и быть не должно. Объединение не знает, какую версию имела в виду Магистраль, поэтому собрало беды обеих веток. Гильдия, получив такой отказ, добавит route в кадр второй версии и окончательно запутается.

Версию надо выбрать до разбора, по признаку, который кадр несёт сам. Здесь признак есть: поле version. Есть поле, кадр разбирается только как v2. Нет поля, только как v1 с миграцией. Тогда отказ говорит о той версии, которую прислали:

[ 'строка 1: path.tower: код башни вида T-число' ]

Как заглянуть в кадр, не разбирая его целиком, решай сам. Подсказка из урока 77: у схемы может быть одно необязательное поле, а остальные ей безразличны. Отказ при этом остаётся разбором, а не JSON.parse с as: строка '{"id": 7' тоже должна получить отказ словами, Expected a valid JSON string, а не уронить ночь.

Практика

Итог

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

Красный сургуч ложится на лист, и впервые за весь раздел это настоящая печать, а не клякса. Протокол кадров Академии принят. Ранга за этот заказ нет: следующий ждёт в конце EF12.

Дальше

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

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

Следующий раздел курса это EF10 «Магистраль»: потоки, обратное давление и повторы без дублей. Начинается он с урока 85.