|
1 | 1 | #include "service_table.h" |
2 | 2 | #include <ydb/core/grpc_services/base/base.h> |
| 3 | +#include <ydb/core/grpc_services/base/flow_control.h> |
3 | 4 |
|
4 | 5 | #include "rpc_common/rpc_common.h" |
5 | 6 | #include "rpc_kqp_base.h" |
@@ -155,7 +156,7 @@ class TStreamExecuteScanQueryRPC : public TActorBootstrapped<TStreamExecuteScanQ |
155 | 156 |
|
156 | 157 | TStreamExecuteScanQueryRPC(TEvStreamExecuteScanQueryRequest* request, ui64 rpcBufferSize) |
157 | 158 | : Request_(request) |
158 | | - , RpcBufferSize_(rpcBufferSize) {} |
| 159 | + , FlowControl_(rpcBufferSize) {} |
159 | 160 |
|
160 | 161 | void Bootstrap(const TActorContext &ctx) { |
161 | 162 | this->Become(&TStreamExecuteScanQueryRPC::StateWork); |
@@ -250,32 +251,30 @@ class TStreamExecuteScanQueryRPC : public TActorBootstrapped<TStreamExecuteScanQ |
250 | 251 | void Handle(TRpcServices::TEvGrpcNextReply::TPtr& ev, const TActorContext& ctx) { |
251 | 252 | LOG_DEBUG_S(ctx, NKikimrServices::RPC_REQUEST, this->SelfId() << " NextReply" |
252 | 253 | << ", left: " << ev->Get()->LeftInQueue |
253 | | - << ", queue: " << GRpcResponsesSizeQueue_.size() |
254 | | - << ", used memory: " << GRpcResponsesSize_ |
255 | | - << ", buffer size: " << RpcBufferSize_); |
| 254 | + << ", queue: " << FlowControl_.QueueSize() |
| 255 | + << ", inflight bytes: " << FlowControl_.InflightBytes() |
| 256 | + << ", limit bytes: " << FlowControl_.InflightLimitBytes()); |
256 | 257 |
|
257 | | - while (GRpcResponsesSizeQueue_.size() > ev->Get()->LeftInQueue) { |
258 | | - GRpcResponsesSize_ -= GRpcResponsesSizeQueue_.front(); |
259 | | - GRpcResponsesSizeQueue_.pop(); |
| 258 | + while (FlowControl_.QueueSize() > ev->Get()->LeftInQueue) { |
| 259 | + FlowControl_.PopResponse(); |
260 | 260 | } |
261 | | - Y_DEBUG_ABORT_UNLESS(GRpcResponsesSizeQueue_.empty() == (GRpcResponsesSize_ == 0)); |
262 | | - LastDataStreamTimestamp_ = TAppData::TimeProvider->Now(); |
263 | 261 |
|
264 | | - if (WaitOnSeqNo_ && RpcBufferSize_ > GRpcResponsesSize_) { |
265 | | - ui64 freeSpace = RpcBufferSize_ - GRpcResponsesSize_; |
| 262 | + LastDataStreamTimestamp_ = TAppData::TimeProvider->Now(); |
266 | 263 |
|
| 264 | + const i64 freeSpaceBytes = FlowControl_.FreeSpaceBytes(); |
| 265 | + if (freeSpaceBytes > 0 && LastSeqNo_ && AckedFreeSpaceBytes_ <= 0) { |
267 | 266 | LOG_DEBUG_S(ctx, NKikimrServices::RPC_REQUEST, this->SelfId() << " Send stream data ack" |
268 | | - << ", seqNo: " << *WaitOnSeqNo_ |
269 | | - << ", freeSpace: " << freeSpace |
| 267 | + << ", seqNo: " << *LastSeqNo_ |
| 268 | + << ", freeSpace: " << freeSpaceBytes |
270 | 269 | << ", to: " << ExecuterActorId_); |
271 | 270 |
|
272 | 271 | auto resp = MakeHolder<NKqp::TEvKqpExecuter::TEvStreamDataAck>(); |
273 | | - resp->Record.SetSeqNo(*WaitOnSeqNo_); |
274 | | - resp->Record.SetFreeSpace(freeSpace); |
| 272 | + resp->Record.SetSeqNo(*LastSeqNo_); |
| 273 | + resp->Record.SetFreeSpace(freeSpaceBytes); |
275 | 274 |
|
276 | 275 | ctx.Send(ExecuterActorId_, resp.Release()); |
277 | 276 |
|
278 | | - WaitOnSeqNo_.Clear(); |
| 277 | + AckedFreeSpaceBytes_ = freeSpaceBytes; |
279 | 278 | } |
280 | 279 | } |
281 | 280 |
|
@@ -349,28 +348,22 @@ class TStreamExecuteScanQueryRPC : public TActorBootstrapped<TStreamExecuteScanQ |
349 | 348 | TString out; |
350 | 349 | Y_PROTOBUF_SUPPRESS_NODISCARD response.SerializeToString(&out); |
351 | 350 |
|
352 | | - GRpcResponsesSizeQueue_.push(out.size()); |
353 | | - GRpcResponsesSize_ += out.size(); |
| 351 | + FlowControl_.PushResponse(out.size()); |
| 352 | + const i64 freeSpaceBytes = FlowControl_.FreeSpaceBytes(); |
| 353 | + LastSeqNo_ = ev->Get()->Record.GetSeqNo(); |
| 354 | + AckedFreeSpaceBytes_ = freeSpaceBytes; |
354 | 355 |
|
355 | 356 | Request_->SendSerializedResult(std::move(out), StatusIds::SUCCESS); |
356 | 357 |
|
357 | | - ui64 freeSpace = GRpcResponsesSize_ < RpcBufferSize_ |
358 | | - ? RpcBufferSize_ - GRpcResponsesSize_ |
359 | | - : 0; |
360 | | - |
361 | | - if (freeSpace == 0) { |
362 | | - WaitOnSeqNo_ = ev->Get()->Record.GetSeqNo(); |
363 | | - } |
364 | | - |
365 | 358 | LOG_DEBUG_S(ctx, NKikimrServices::RPC_REQUEST, this->SelfId() << " Send stream data ack" |
366 | 359 | << ", seqNo: " << ev->Get()->Record.GetSeqNo() |
367 | | - << ", freeSpace: " << freeSpace |
| 360 | + << ", freeSpace: " << freeSpaceBytes |
368 | 361 | << ", to: " << ev->Sender |
369 | | - << ", queue: " << GRpcResponsesSizeQueue_.size()); |
| 362 | + << ", queue: " << FlowControl_.QueueSize()); |
370 | 363 |
|
371 | 364 | auto resp = MakeHolder<NKqp::TEvKqpExecuter::TEvStreamDataAck>(); |
372 | 365 | resp->Record.SetSeqNo(ev->Get()->Record.GetSeqNo()); |
373 | | - resp->Record.SetFreeSpace(freeSpace); |
| 366 | + resp->Record.SetFreeSpace(freeSpaceBytes); |
374 | 367 |
|
375 | 368 | ctx.Send(ev->Sender, resp.Release()); |
376 | 369 | } |
@@ -411,9 +404,9 @@ class TStreamExecuteScanQueryRPC : public TActorBootstrapped<TStreamExecuteScanQ |
411 | 404 | TInstant now = TAppData::TimeProvider->Now(); |
412 | 405 | TDuration timeout; |
413 | 406 | LOG_DEBUG_S(ctx, NKikimrServices::RPC_REQUEST, "Got timeout event, InactiveClientTimeout: " << InactiveClientTimeout_ |
414 | | - << " GRpcResponsesSizeQueue: " << GRpcResponsesSizeQueue_.size()); |
| 407 | + << " GRpcResponsesSizeQueue: " << FlowControl_.QueueSize()); |
415 | 408 |
|
416 | | - if (InactiveClientTimeout_ && GRpcResponsesSizeQueue_.size() > 0) { |
| 409 | + if (InactiveClientTimeout_ && FlowControl_.QueueSize() > 0) { |
417 | 410 | TDuration processTime = now - LastDataStreamTimestamp_; |
418 | 411 | if (processTime >= InactiveClientTimeout_) { |
419 | 412 | auto message = TStringBuilder() << this->SelfId() << " Client cannot process data in " << processTime |
@@ -477,13 +470,12 @@ class TStreamExecuteScanQueryRPC : public TActorBootstrapped<TStreamExecuteScanQ |
477 | 470 |
|
478 | 471 | private: |
479 | 472 | std::shared_ptr<TEvStreamExecuteScanQueryRequest> Request_; |
480 | | - const ui64 RpcBufferSize_; |
| 473 | + TRpcFlowControlState FlowControl_; |
| 474 | + TMaybe<ui64> LastSeqNo_; |
| 475 | + i64 AckedFreeSpaceBytes_ = 0; |
481 | 476 |
|
482 | 477 | TDuration InactiveClientTimeout_; |
483 | | - TQueue<ui64> GRpcResponsesSizeQueue_; |
484 | | - ui64 GRpcResponsesSize_ = 0; |
485 | 478 | TInstant LastDataStreamTimestamp_; |
486 | | - TMaybe<ui64> WaitOnSeqNo_; |
487 | 479 |
|
488 | 480 | TSchedulerCookieHolder TimeoutTimerCookieHolder_; |
489 | 481 |
|
|
0 commit comments