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