• Nikitos's avatar
    Симуляция задержки сети: очередь отложенных отправок
    · 9a5b45c5
    Nikitos создал
    §12.15: «симуляция задержки пакетов» числилась незакрытой — и в C это было
    написано прямым текстом: `R2D_UNUSED(delay_ms); // задержку пока не откладываем:
    только потери`. Потери работали, задержки не было.
    
    ЧТО СДЕЛАНО:
    * C: r2d_net_send разделён на обёртку (симуляция) и r2d__net_send_now (реальная
      отправка). Задержка — ОЧЕРЕДЬ отложенных отправок (64 пакета): пакет кладётся
      со временем «когда отправить», реально уходит из r2d_net_tick, который зовёт
      poll() раз в кадр. Спать в кадре нельзя — поэтому именно очередь;
    * jitter: случайная добавка [0, jitter) к задержке, из того же xorshift, что и
      потери, поэтому воспроизводимо от сида;
    * потери применяются ПРИ ПОСТАНОВКЕ, поэтому потерянный пакет очередь не
      занимает;
    * очередь переполнена — ОДНО предупреждение в журнал и пакет теряется, кадр не
      роняется;
    * engine.netSimulate(loss, delay, seed, jitter), engine.netDelayed();
    * $.net.simulate({loss, delay, jitter, seed}), simulation(), delayed(),
      simulateOff().
    
    ПРОВЕРКА (tests/agent/net_delay_test.py, 14 проверок, ДВА движка на localhost):
    без задержки пакет доходит быстро; с delay 200 сразу после send пакет В ОЧЕРЕДИ
    (netDelayed = 1) и до сервера НЕ дошёл, а через ~0.16 с дошёл; simulateOff
    возвращает быстроту; 100% потерь — не доходит ничего. То есть проверяется не
    «настройка сохранилась», а что задержка ДЕЙСТВИТЕЛЬНО задерживает.
    
    ЧЕСТНОЕ ОГРАНИЧЕНИЕ: симуляция не моделирует переупорядочивание и дубли —
    пакеты теряются и задерживаются, но не приходят в другом порядке. Записано в
    net.md §8.
    
    ДОКИ: net.md §8 (поля, почему очередь, ограничения), API.md (две функции),
    TASKS §12.15 (осталось только сглаживание откатов).
    
    Полный qjs, агентские тесты, doc_coverage, doc_claims, duplicate_keys, быстрый
    набор — зелёные.
    9a5b45c5