|
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