Есть ли у C# реализация gRPC обратное давление потоковой передачи?

У меня есть служба gRPC, которая принимает потоковые сообщения от клиента. Клиент отправляет сообщения с конечной последовательностью на сервер с высокой скоростью.

В результате сервер буферизует большое количество сообщений (> 1 ГБ), и его использование памяти резко возрастает, а затем медленно истощается при обработке.

Я обнаружил, что даже если я жду всех асинхронных вызовов, клиент просто продолжает посылать сообщения так быстро, как только может. Я бы хотел, чтобы клиент замедлился.

Я реализовал явный ответ ack, который клиент ожидает перед отправкой следующего сообщения, но так как в http/2 уже встроена семантика управления потоком, я чувствую, что немного изобретаю колесо.

У меня есть два конкретных вопроса.

  1. Реализация C# автоматически применяет противодавление? Например, если вызывающая сторона медленно вызывает MoveNext в асинхронном потоке, будет ли клиентской стороне дольше возвращаться из своих вызовов в WriteAsync?

  2. Есть ли в реализации C# gRPC какой-либо настраиваемый способ ограничения буферизации сообщений для потокового вызова rpc. Например, ограничение количества буферизованных сообщений или ограничение объема пространства в буфере вызова.

1 ответ

Как прокомментировал Ян, на этот вопрос был дан ответ на репозитории gRPC GitHub здесь.

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

Более конкретно:

  1. если одна сторона медленно запрашивает сообщения (MoveNext()), отправляющая сторона в конечном итоге будет "заблокирована" при отправке (WriteAsync() займет больше времени, и вы можете иметь только для операции WriteAsync () выполняющуюся для вызова),

  2. Я считаю, что такие параметры могут быть настроены через аргумент канала C-core (ChannelOption в C#).

Другие вопросы по тегам