Skip to content

perf(extensions): apply backpressure to the JSON-RPC stdio stream (#893) - #979

Merged
ZhuchkaTriplesix merged 1 commit into
devfrom
issue/893-jsonrpc-stdio-backpressure
Sep 25, 2026
Merged

ZhuchkaTriplesix merged 1 commit into
devfrom
issue/893-jsonrpc-stdio-backpressure

Conversation

@ZhuchkaTriplesix

Copy link
Copy Markdown
Member

Описание изменений

  • Backpressure в JsonRpcStdioClient. Клиент считает строки и байты, ожидающие обработки, и ставит чтение stdout драйвера на паузу выше 256 строк или 16 МиБ, а возобновляет при половине любого лимита (maxBufferedLines, maxBufferedBytes, значения по умолчанию в json_rpc_payload_limits.dart). Драйвер тогда упирается в буфер ОС-пайпа, а не в память клиента. Одна строка больше лимита всё равно принимается (до maxLineBytes): чтение просто ждёт её обработки.
  • boundedUtf8LineSplitter пробрасывал паузу не дальше контроллера. Раньше pause() подписчика лишь заставлял контроллер копить декодированные строки, а источник байтов продолжал читаться. Теперь onPause / onResume управляют исходной подпиской.
  • Найденная по ходу потеря ответов. При закрытии stdout ожидающие запросы падали с Plugin stdout closed сразу, даже если ответы уже пришли и ждали декодирования (крупные строки декодируются в изоляте). Плагин, который отвечает и сразу завершается, терял последние ответы. Теперь остаток запросов падает только после того, как очередь обработана. Это выходит за текст issue, но напрямую связано с очередью строк.
  • Геттеры bufferedLineCount и isReadPaused для диагностики и тестов.

Замер (300 строк по 300 КБ, плагин в том же процессе, изолят-декодирование включено)

строк «в полёте» в пике прирост RSS
до (2 прогона) 300 179 МБ
после (2 прогона) 55 170–181 МБ

Очередь необработанных строк ограничена (300 → 55), но прирост RSS в этом замере не изменился: генератор-плагин работает в том же процессе и сам порождает мусор (jsonEncode / utf8.encode 300 КБ на строку), а RSS не отражает мгновенный размер живой кучи. Поэтому экономию памяти цифрами я показать не смог. В реальном сценарии плагин отдельный процесс, и его данные остаются в пайпе ОС, а не в нашей куче, так что ограничение очереди должно снижать пик, но это не измерено. Замер с реальным драйвером не делал. Время на прогон слегка вырастает (5,6 против 6,4 и 9,1 с при шуме), пауза чуть простаивает конвейер.

Тесты

json_rpc_stdio_client_test (6 новых): пауза источника пробрасывается сплиттером; стоп/старт при накоплении очереди и возобновление после; быстрый источник не уводит очередь за лимит; лимит по байтам; ответы, стоявшие в очереди при закрытии stdout, доставляются. Весь test/core/extensions и test/features/extensions (155 тестов) прогнал локально, проходят.

Не входит

Смена транспорта (shared memory / сокеты), как в issue.

Связанные Issue

Closes #893

…oses #893)

JsonRpcStdioClient consumed a driver's stdout eagerly, and every received line
was queued as a closure on the handling chain, so a plugin streaming NDJSON
faster than it was decoded grew the backlog without bound.

- The client counts lines and bytes waiting to be handled and pauses stdout
  above 256 lines or 16 MiB, resuming at half of either limit; the OS pipe then
  throttles the plugin instead of our heap.
- boundedUtf8LineSplitter now forwards pause/resume to the byte source. Before,
  pausing the consumer only made the controller buffer decoded lines while the
  source kept being read.
- Fix a related loss: on stdout close, pending requests were failed immediately
  even when their replies were still queued for (isolate) decoding. They are now
  failed only after the backlog has been handled.
@github-actions github-actions Bot added performance Theme parser epic label: performance stability Theme parser epic label: stability marketplace Extensions marketplace, ExtensionManifest labels Sep 25, 2026
@github-actions github-actions Bot added this to the 0.4.18 milestone Sep 25, 2026
@ZhuchkaTriplesix
ZhuchkaTriplesix merged commit c3ca23d into dev Sep 25, 2026
4 checks passed
@ZhuchkaTriplesix
ZhuchkaTriplesix deleted the issue/893-jsonrpc-stdio-backpressure branch September 28, 2026 08:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

marketplace Extensions marketplace, ExtensionManifest performance Theme parser epic label: performance stability Theme parser epic label: stability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant