Протокол, который живёт дольше года, обязательно получает вторую версию. Старую при этом не выключить в один день: на другом конце провода чужие башни, и у каждой свой график. Значит, надо уметь читать обе, а писать одну. Всё для этого уже есть в разделе: схемы с двумя сторонами из урока 79, цепочка Hop из урока 82, отказы словами из урока 81. Сегодня их надо сложить.
Что нужно башне
Тесты накопительные. Сверху новый модуль src/version.ts.
- Две версии. Первая это кадр урока 79,
StampedFrame, как есть: маршрут парой, ретранслятор отдельным полем. Вторая несёт полеversion: 2и вместо маршрута и ретранслятора цепочкуpath: Hop. - Миграция при разборе. Кадр первой версии, пройдя разбор, становится кадром второй. Цепочка
откуда, куда, а если был ретранслятор,откуда, ретранслятор, куда. Остальные поля переезжают как есть,sentAtостаётся тем же моментом. Все проверки первой версии работают и при миграции: маршрут из одной башни дважды не пройдёт. - Наружу только v2. Входящая схема разбирает строку JSON любой версии и отдаёт
FrameV2. Исходящая пишет только v2. Записать кадр первой версией Академия не может вовсе: такая запись запрещена в самой схеме. - Ночь.
nightIntake(lines)разбирает ночь строк Магистрали. Ошибок в типе нет, мусор ночь не роняет. В отчёте принятые кадры в порядке строк, число пришедших первой версией и отказы видастрока N: беда; беда, все беды сразу, словамиexplain. - Отказ про ту версию, что прислали. Об этом ниже: это главная ловушка заказа.
Чек-лист перед сдачей
- Тесты всех прошлых этапов зелёные.
- Кадр v1 с ретранслятором даёт цепочку из трёх башен, без него из двух.
- Кадр v1 с маршрутом из одной башни дважды не проходит и после миграции.
- Исходящая и входящая схемы записывают один и тот же кадр v2.
- Битый кадр v2 получает отказ только про поля второй версии.
- Пустая ночь:
{ 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.