Ночь Магистрали теперь знакома целиком: строки приходят потоком (урок 85), их нельзя брать быстрее, чем башня успевает (урок 86), дальше они уходят пачками со сроком (урок 87), а то, что не разобралось, становится мёртвым письмом (урок 88). Сегодня это одна функция, и ещё одна вещь, о которой Ринцвальд сказал вчера: дубли.
Что нужно башне
Тесты накопительные. Сверху новый модуль src/station.ts.
- Ночь потоком.
relayNight(lines, send, options)читает строки из потокаlines, отправляет чужие кадры черезsendи в конце отдаёт отчёт. Ошибок разбора в типе нет: мусор ночь не роняет. Ошибка самой линии, обрыв провода, проходит наружу как есть: это авария, а не мусор. - Дубли. Магистраль повторяет кадр, если не услышала подтверждения. Повтор это кадр с тем же номером от той же первой башни цепочки. Каждый такой кадр проходит один раз, повторы только считаются в
duplicates. Тот же номер от другой первой башни это другой кадр. - Свои и чужие. Кадр, у которого последняя башня цепочки
options.self, свой: его номер идёт вdeliveredв порядке строк. Остальные отправляются дальше. - Пачки. Чужие кадры уходят пачками не больше
batchSize. Неполная пачка уходит черезwithinпосле первого кадра в ней, не дожидаясь следующих. Номера кадров ушедшей пачки идут вforwarded, пачка за пачкой. - Повтор пачки. Пачку, которую линия не приняла (
UplinkDown), отправляют ещё раз, всего не больше трёх попыток. Не ушла и с третьей, и каждый её кадр становится мёртвым письмом с бедойне ушло: причина. - Мёртвые письма. Мусор и неушедшие кадры в
dead, по номеру строки, строки с единицы. У письма из мусора беды словами, как уreadLine. - Каждый запуск это новая ночь. Запустил программу дважды, получил два одинаковых отчёта: никакой памяти между запусками.
Чек-лист перед сдачей
- Тесты всех прошлых этапов зелёные.
- Кадр, присланный трижды, доставлен один раз,
duplicatesравно двум. - Пять чужих кадров и
batchSize: 2дают пачки из двух, двух и одного. - Кадр, после которого линия молчит дольше
within, ушёл до того, как пришёл следующий. - Пачка, которая не ушла трижды, стала мёртвыми письмами, и письма стоят по номеру строки вместе с мусором.
- Пустая ночь:
{ delivered: [], forwarded: [], duplicates: 0, dead: [] }.
Магистраль, этап 14
Подумай до кода
Почти всё здесь уже написано в relay.ts и letters.ts. Работа босса в том, чтобы сложить это в одну ночь и не потерять по дороге то, что нужно отчёту.
- Письму нужна строка. Мёртвое письмо помнит номер и текст строки. Для мусора это уже есть:
sortLinesиз урока 88. Но кадр, который разобрался и не ушёл с пачкой, тоже станет письмом, а к этому времени он давно кадр, а не строка. Значит, от разбора до отправки кадр должен ехать вместе со своей строкой. - Память о дублях живёт одну ночь. Башня должна помнить ключи кадров, которые уже прошли. Где эта память создаётся? Если снаружи функции, второй запуск начнёт с памятью первого и посчитает дублем всю ночь. Вспомни урок 30: свиток, который запускают дважды, исполняется дважды с начала.
- Дубль узнают до пачки. Если отсеять повторы после
groupedWithin, два одинаковых кадра поедут в одной пачке и Магистраль получит дубль уже от нас. - Свои кадры в пачку не идут. Им не нужна линия дальше: они уже дома.
- Повтор и идемпотентность. Ты повторяешь пачку, если линия не ответила. Ровно так же, как Магистраль повторяет кадр. Чем твой повтор лучше? Тем, что на том конце башня, которая помнит ключи, а ключ у кадра в пачке тот же. Это и есть идемпотентность: повтор безопасен, когда получатель узнаёт уже полученное. Без этого любой повтор это дубль.
Рассказ Ринцвальда
Дыры сегодня нет. Вместо неё Ринцвальд, который вчера объяснил дубли, сидит рядом и рассказывает, как это выглядит с той стороны.
Сюжетный квест
Вторая улика квеста «Проглоченная ошибка Гилта». Первая лежит в боссе обработчика кадров, третья в боссе честного Почтамта.
Практика
Итог
Утром Рыдкулл читает отчёт ночи: сорок два кадра доставлено, триста восемь ушло дальше в тридцати одной пачке, двести шестнадцать дублей, девять мёртвых писем, и у каждого номер строки. Он долго смотрит на число дублей.
Ринцвальд стоит у двери с рулоном своей старой скорописи под мышкой. Он кладёт его Рыдкуллу на стол.
Шляпа с надписью «ВАЛШЕБНИК» висит на крючке у двери Академии. Ранга за этот заказ нет: следующий ждёт в конце EF12.
Дальше
Последним приходит Липвиг. Он кладёт на стол поверх отчёта ночи большой лист: план Почтамта. Окошки, книги, ящики, письма по адресу, и стрелка от каждого окошка к башне T-1.
Следующий раздел курса это EF11 «Почтамт»: HTTP, RPC, база данных и платформа. Начинается он с урока 90.